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。

上面这几个参数我以前经常容易被混淆,不过后来根据字母拆分就简单了很多。

如下图:

Java xss大小 -xss jvm_jvm

还有几个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参数之前文章有详细讲过,这里就不再赘述了,具体看下图:

Java xss大小 -xss jvm_算法_02

配置的最后两个参数介绍:

■ -XX:+PrintGCDetails:打印GC详细信息;

■ -XX:SurvivorRatio=8:eden/survivor=8;

运行结果如下图:

Java xss大小 -xss jvm_编程语言_03

可以看到输出了一些主要内容,对主要的内容解释如下:

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。

在代码中加入一个字节数组如下图:

Java xss大小 -xss jvm_jvm_04

可以看到新生代的内存使用比上一个测试增加了512k(3243-2731=513),字节数组长度是512*1024,1024个字节等于1k。这说明数组确实存放到了堆的新生代!

四、总结

这个jvm参数是基于jdk8版本,在jdk9后参数设置进行了大改版,以后专门再去学习,不过学习了解jdk8的参数也是对jvm的学习,内容不会变,比较现在主流仍然是jdk8。

通过对参数的学习和测试,我们才能真正清楚参数起到的作用,并且只有实践才能更好的理解。比如上面的测试知道数组在内存中的分配和占用的大小,并且知道了我的jdk默认的垃圾收集器是Parallel Scavenge+Parallel Old。大家有兴趣也可以测试下!