jvm参数文档:
Java Performance
https://docs.oracle.com/javase/7/
https://docs.oracle.com/javase/8/
英文很吃力,中文的很多抄袭(“促使内存”错别字也不改),而且规范和实践难免脱节.
太祖有训曰: 实事求是,不要教条主义; 太宗亦曰: 实践是检验真理的唯一标准
1、常用jvm命令(命令本身自带帮助文档,如jstack)
1.1、查看帮助文档的命令:
- 命令本身,形如:jstat
- linux的man, 形如:man jstat //更详细
1.1、命令使用异常:
- 异常输出:
- Unable to open socket file: target process not responding or HotSpot VM not loaded The -F option can be used when the target process is not responding
- Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can’t attach to the process
- 解决方案:
- 命令和程序使用同一个账号。
- 使用root账号。
- 加-F,部分命令有效果,如 jstack -l -F PID //-F会让线程改变线程名称?
1.3、命令详解:
- 1, jps 查看java进程
timeriver@king:/opt/tmp$ jps
15674 Jps
15291 HeapTest
- 2, jstat 查看统计信息, 语法:
jstat -<option> PID [-t] [-h<lines>]
timeriver@king:/opt/tmp$ jstat -gc 15291 1000 10
<option> //必选项,可以通过man jstat查看帮助文档。类似html的<select>的<option>元素
- 3, jstack 查看堆栈, 语法:jstack -l PID
//判断代码死循环,或者代码在何处hangs(wait,sleep,block ...)
- 4, jinfo 查看参数配置, 语法:
jinfo -<option> PID
timeriver@king:/opt/tmp$ jinfo -flag MaxPermSize 15291
-XX:MaxPermSize=134217728
- 5, jmap 查看内存映射, 语法:
jmap -<option> PID
, 常用的有
- jmap -heap PID //heap summary, heap configuration, GC algorithm used, //ubuntu下需要root权限好奇怪
- jmap -histo:live PID //查看明细统计
- jmap -permstat PID //查看永久代统计,
jdk8为jmap -clstats PID
- jmap -dump:format=b,file=fileName PID //dump内存快照
2、验证Java 7内存模型
2.1、验证代码
/**
* vm args: -Xms500m -Xmx1g -Xmn200m
* @auther timeriver
* @date 18-4-19 下午15:36
*/
public class HeapTest {
public static void main(String[] args) throws InterruptedException {
List<BigBean> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
System.out.println(i);
list.add(new BigBean());
}
}
static class BigBean{
int size = 1024 * 1024 * 60;
byte[] content = new byte[size];
}
}
2.2、验证命令: jmap -heap PID
- -Xms500m=初始堆内存(young+old) //后面old突破了300M扩展为510M
- -Xmx1g=最大堆内存(超过jvm crash, 默认为2g)
- -Xmn200m=年轻代内存(设置的话,就固定大小了)
- jmap和javac的版本不一致 Caused by: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 24.80-b11. Target VM is 25.151-b12
- ubuntu需要root权限
下面是第一次循环的输出(可以加上断点每次循环都输出)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 1048576000 (1000.0MB)
NewSize = 209715200 (200.0MB)
MaxNewSize = 209715200 (200.0MB) //新生代
OldSize = 5439488 (5.1875MB) //老年代默认值?会自动增长
NewRatio = 2
SurvivorRatio = 8
PermSize = 21757952 (20.75MB) //形如:-XX:PermSize=64M
MaxPermSize = 85983232 (82.0MB) //形如:-XX:MaxPermSize=128M
G1HeapRegionSize = 0 (0.0MB) //G1哦
Heap Usage:
PS Young Generation
Eden Space:
capacity = 157286400 (150.0MB)
used = 6291568 (6.0001068115234375MB)
free = 150994832 (143.99989318847656MB)
4.000071207682292% used
From Space:
capacity = 26214400 (25.0MB)
used = 0 (0.0MB)
free = 26214400 (25.0MB)
0.0% used
To Space:
capacity = 26214400 (25.0MB)
used = 0 (0.0MB)
free = 26214400 (25.0MB)
0.0% used
PS Old Generation
capacity = 314572800 (300.0MB)
//capacity = 535298048 (510.5MB) //i=5时,old突破了300M扩展为510M
used = 0 (0.0MB)
free = 314572800 (300.0MB)
0.0% used
PS Perm Generation
capacity = 22020096 (21.0MB)
used = 2683976 (2.5596389770507812MB)
free = 19336120 (18.44036102294922MB)
12.188757033575149% used
2.3、环境切换为java 1.8, Perm区改为了Metaspace
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 1048576000 (1000.0MB)
NewSize = 209715200 (200.0MB)
MaxNewSize = 209715200 (200.0MB)
OldSize = 314572800 (300.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB) //-XX:PermSize=64M 无效
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB //-XX:MaxPermSize=128M
G1HeapRegionSize = 0 (0.0MB)