jvm的参数有很多,必须知道参数分类并且记住面试常见的几个参数。
一、jvm参数分类
根据jvm参数开头可以区分参数类型,共三类:“-”、“-X”、“-XX”,
标准参数(-):所有的JVM实现都必须实现这些参数的功能,而且向后兼容;
例子:-verbose:class,-verbose:gc,-verbose:jni……
非标准参数(-X):默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;
例子:Xms20m,-Xmx20m,-Xmn20m,-Xss128k……
非Stable参数(-XX):此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;
例子:-XX:+PrintGCDetails,-XX:-UseParallelGC,-XX:+PrintGCTimeStamps……
二、关键参数详解
最重要和常见的几个参数如下:
■ -Xms20m:设置jvm初始化堆大小为20m,一般与-Xmx相同避免垃圾回收完成后jvm重新分。
■ -Xmx20m:设置jvm最大可用内存大小为20m。
■ -Xmn10m:设置新生代大小为20m。
■ -Xss128k:设置每个线程的栈大小为128k。
上面这几个参数我以前经常容易被混淆,不过后来根据字母拆分就简单了很多。
如下图:
还有几个GC的参数见名知意就不详解了,后面测试会一一说明,主要的如下:
■ -verbose:gc:可以输出每次GC的一些信息;
■ -XX:-UseConcMarkSweepGC:使用CMS收集器;
■ -XX:-UseParallelGC;
■ -XX:-UseSerialGC;
■ -XX:CMSInitiatingOccupancyFraction=80 CMS gc,表示在老年代达到80%使用率时马上进行回收;
■ -XX:+printGC;
■ -XX:+PrintGCDetails:打印GC详情;
■ -XX:+PrintGCTimeStamps:打印时间戳;
三、jvm参数设置和测试
在idea设置jvm参数之前文章有详细讲过,这里就不再赘述了,具体看下图:
配置的最后两个参数介绍:
■ -XX:+PrintGCDetails:打印GC详细信息;
■ -XX:SurvivorRatio=8:eden/survivor=8;
运行结果如下图:
可以看到输出了一些主要内容,对主要的内容解释如下:
PSYoungGen:其中PS是Parallel Scavenge的简写,整个就表示新生代采用了Parallel Scavenge收集器。
后面紧跟total参数:表示新生代使用内存9216k,只有9M是因为只计算了eden和from survivor,我们知道to survivor在jvm运行时是预留的,只有在回收的时候才会使用。刚刚设置新生代内存是10M、eden/survivor=8,刚刚验证了配置参数。
eden space 8192K, 33% used:eden区域总共8192k,使用了33%。2731/8192约等于0.33。
from space 1024K, 0% used;
to space 1024K, 0%used:因为还没有进行过回收所以两个survivor区域都是空的;
ParOldGen total 10240K, used 0K:Par是Parallel Old的简写,所以老年代采用的是Parallel Old收集器进行垃圾回收。
Metaspace used 3312K:元空间,因为用的是本地内存,所以没有total只有used。
在代码中加入一个字节数组如下图:
可以看到新生代的内存使用比上一个测试增加了512k(3243-2731=513),字节数组长度是512*1024,1024个字节等于1k。这说明数组确实存放到了堆的新生代!
四、总结
这个jvm参数是基于jdk8版本,在jdk9后参数设置进行了大改版,以后专门再去学习,不过学习了解jdk8的参数也是对jvm的学习,内容不会变,比较现在主流仍然是jdk8。
通过对参数的学习和测试,我们才能真正清楚参数起到的作用,并且只有实践才能更好的理解。比如上面的测试知道数组在内存中的分配和占用的大小,并且知道了我的jdk默认的垃圾收集器是Parallel Scavenge+Parallel Old。大家有兴趣也可以测试下!