JVM 参数配置和基础说明
JVM 虚拟机 HOTSPOT 下,JDK1.6 1.7 1.8 三个不同的版本下,堆和永久代的 内存区别,
我自己查了一下博客,参考他人博客的理解,若有错,欢迎拍砖
Hotspot
JVM 分5个部分
- 方法区 ,又叫永久代 线程共享
- 虚拟机栈 ,线程栈,线程独享内存,存储线程基本变量,方法参数等
- 本地方法栈 ,本地方法native方法信息,线程独享
- 程序计算器 ,线程独享,线程指令记录
- 堆 线程共享,数据对象存放区域,年轻代,年老代,GC
JVM 配置
- -Xmx : -Xmx2g 堆最大内存 2g
- -Xms: -Xms2g 堆初始大小2g ,最好和-Xmx 分配大小一致,减少内存重新分配带来的性能消耗
- -Xmn: -Xmn500m 年轻代大小500m
- -XX:NewSize=500m 年轻代大小500m
- -XX:NewRatio=2 年轻代:年老代 =1:2
- -XX:SurvivorRatio=8 年轻代区中,Eden : s0 = 8:1 ,可能会无效
- -Xxx :-Xss 线程栈大小,决定单线程处理的数据多少和栈深度
- -XX:PermSize=100m 永久代初始大小,JDK8 废弃改配置,使用-XX:MetaspaceSize
- -XX:MaxPermSize=300m 永久代最大大小 ,JDK8 废弃改配置,使用-XX:MaxMetaspaceSize
- -XX:MetaspaceSize=100m 元空间初始大小,JDK8 才有的属性
- -XX:MaxMetaspaceSize=300m, 元空间最大值,JDK8 才有的属性
- -XX:+UseParallelGc=4 并行开启多少线程执行GC
- -XX:+CMSInitiatingOccupancyFraction=80 到达百分之80的时候执行GC
- -XX:+MaxTenuringThreshold=10 对象在年轻代经历10次GC后转年老代
- -XX:+HeapDumpOnOutOfMemoryError 打印dump日志在内存溢出异常的时候
- -XX:HeapDumpPath=/home/log/gc.log dump日志路径
- -Xloggc:/root/hzsmk/tomcat8080/temp_gc.log gc日志
其中有3个参数 -Xmn -XX:NewSize -XX:NewRatio 都可以设置年轻代的大小,那他们一起出现的时候的优先级是什么样的呢?
我找了一个 tomcat 测试了一下,使用 jmap -heap 8764 查看内存信息
JAVA_OPTS=" -Xms512m -Xmx512m
-XX:NewRatio=2(第一位) -Xmn100m (第二位) -XX:NewSize=150m (第三位) "
3个参数一起配置的时候
第一配置 | 第二配置 | 第三配置 | 年轻代初始大小 |
---|---|---|---|
-XX:NewSize=150m | -XX:NewRatio=2 | -Xmn100m | 100m |
-XX:NewSize=150m | -Xmn100m | -XX:NewRatio=2 | 100m |
-Xmn100m | -XX:NewSize=150m | -XX:NewRatio=2 | 150m |
-Xmn100m | -XX:NewRatio=2 | -XX:NewSize=150m | 150m |
-XX:NewRatio=2 | -XX:NewSize=150m | -Xmn100m | 100m |
-XX:NewRatio=2 | -Xmn100m | -XX:NewSize=150m | 150m |
说明三个参数在一起的时候 -XX:NewRatio=2 无效 ,同时 -XX:NewSize=150m, -Xmn100m 靠后的配置有效
2个参数一起配置的时候
JAVA_OPTS=" -Xms512m -Xmx512m
-XX:NewRatio=2(第一位) -Xmn100m (第二位) "
第一配置 | 第二配置 | 年轻代初始大小 |
---|---|---|
-XX:NewSize=150m | -XX:NewRatio=2 | 170m |
-XX:NewSize=150m | -Xmn100m | 100m |
-Xmn100m | -XX:NewSize=150m | 150m |
-Xmn100m | -XX:NewRatio=2 | 100m |
-XX:NewRatio=2 | -XX:NewSize=150m | 170m |
-XX:NewRatio=2 | -Xmn100m | 100m |
-Xmn100m 和 -XX:NewSize=150m 遵循靠后原则有效
-Xmn100m 和 -XX:NewRatio=2 Xmn 有效
-XX:NewSize=150m 和 -XX:NewRatio=2 NewRatio有效
如果理解有误,欢迎拍砖
-XX:SurvivorRatio=8 这个参数可能会无效,原因是,在HotSpot VM里,并行系的收集器(UseParallelGC / UseParallelOldGC)默认开启-XX:+UseAdaptiveSizePolicy, 这个配置会在每次Minor GC之后对From和To区进行自适应分配大小,而SurvivorRatio使用默认值8,设置成任何非8的数值都会无效。所以,我这个参数里面的-XX:+UseAdaptiveSizePolicy其实是画蛇添足了。
JVM 异常:
-
java.lang.*Error
这种异常一般是由于代码里面有递归算法处理数据,比如JSON 转换处理
解决办法:1.修改代码。2 如果确实必要做非常深的递归处理,就修改JVM参数 -Xss20m -
java.lang.OutOfMemoryError: PermGen space
永久代内存溢出,JDK8以后不会出现,应为JDK8 以后没有永久代,
解决办法:1.检查项目代码,2. -XX:PermSize=64M -XX:MaxPermSize=128m -
java.lang.OutOfMemoryError: Java heap space
堆栈内存溢出,项目中对象无法被回收,代码错误引起,或者是堆内存不够
解决办法:1.检查项目代码,是否有无法释放对象的地方,2.-Xmx4g -Xms4g -
java.lang.OutOfMemoryError: Metaspace
元空间内存不够,JDK8以上才会出现的错误
解决办法:-XX:MetaspaceSize=100m -XX:MaxMetaspaceSize=300m,
常用linux JVM 工具
- jps -mlvV
- jmap -heap 8765
- jinfo -flags 9876
- jstack 9766 查看进程
- jstat -gcutil 9876 1000 每1000毫秒自动输出GC情况