记录JVM内存模型,参数含义和优化
一.JVM内存模型
(图片来自网络)
根据Java虚拟机规范,JVM将内存划分为:
- New(年轻代)
- Tenured(年老代)
- Perm (永久代)
其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx,-Xms,前者是JVM最大允许分配的堆内存,后者是JVM初始分配的堆内存)指定的内存中分配,Perm不属于堆内存,由虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize 等参数调整其大小。
- 年轻代(New):年轻代用来存放JVM刚分配的Java对象
- 年老代(Tenured):年轻代中经过垃圾回收没有回收掉的对象将被Copy到年老代
- 永久代(Perm):永久代存放Class、Method元信息,其大小跟项目的规模、类、方法的量有关,一般设置为128M就足够,设置原则是预留30%的空间。
New又分为几个部分:
- Eden:Eden用来存放JVM刚分配的对象
- Survivor1
- Survivro2:两个Survivor空间一样大,当Eden中的对象经过垃圾回收没有被回收掉时,会在两个Survivor之间来回Copy,当满足某个条件,比如Copy次数,就会被Copy到Tenured。显然,Survivor只是增加了对象在年轻代中的逗留时间,增加了被垃圾回收的可能性。
二.JVM常见配置
如果想查看JVM的配置参数,可以采用如下方式:
- 启动命令行,输入java,然后回车,查看关于java的所有参数信息列表。(笔者使用windows系统,并且将JAVA_HOME添加进了环境变量。如果你输入java显示“
'java' 不是内部或外部命令,也不是可运行的程序或批处理文件”,此时可以命令行进入jdk的安装目录的bin目录下,再输入java,回车)。效果如下图所示:
- 上述参数列表中,有一个-X的参数,这个参数就是设置JVM虚拟机的,可以输入java -X查看JVM设置的具体设置。效果如下图所示:
上述参数并不是都常用,下面总结出常用的一些配置:
1.堆配置:
- -Xms:初始堆大小
- -Xmx:最大堆大小(如果此值大于-Xms的大小,则按需分配,因此为了避免每次垃圾回收完成后JVM重新分配内存,两个只很多时候设置成相同值)
- -XX:NewSize=n:设置年轻代大小
- -XX:NewRatio=n:设置年轻代和年老代的比值,如:n=3,表示年轻代和年老代比值是1:3
- -XX:SurvivorRatio=m:年轻代中Eden区与两个Survivor区的比值。注意Suvivor区有两个,大小一样大。如:m=3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
- XX:MaxPermSize=p:设置持久代的大小
2.收集器设置
- -XX:+UseSerialGC:设置串行收集器
- -XX:+UseParallelGC:设置并行收集器
- -XX:+UseParalledlOldGC:设置并行年老代收集器
- -XX:+UseConcMarkSweepGC:设置并发收集器
3.垃圾回收统计信息
- -XX:+PrintGC
- -XX:+PrintGCDetails
- -XX:+PrintGCTimeStamps
- -Xloggc:filename
4.并行收集器设置
- -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
- -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
- -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
5.并发收集器设置
- -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
- -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
三.留着补充