- -XX:+HeapDumpOnOutOfMemoryError?
- XX:HeapDumpPath=/opt/app/applogs/68dump.hprof"
- -Xloggc:? /opt/app/applogs/gc.log
- -Xms:
- 初始化堆内存大小,默认为物理内存的1/64(小于1GB)。
- -Xmx:
- 堆内存最大值。**默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。
- -Xmn:
- 新生代大小,包括Eden区与2个Survivor区。
- -XX:
- SurvivorRatio=1:Eden区与一个Survivor区比值为1:1。
- -XX:
- MaxDirectMemorySize=1G:**直接内存。**报java.lang.OutOfMemoryError: Direct buffer memory异常可以上调这个值。
- -XX:
- +DisableExplicitGC:禁止运行期显式地调用System.gc()来触发fulll GC。
- 注意: Java RMI的定时GC触发机制可通过配置-Dsun.rmi.dgc.server.gcInterval=86400来控制触发的时间。
- -XX:
- CMSInitiatingOccupancyFraction=60:老年代内存回收阈值,默认值为68。
- -XX:
- ConcGCThreads=4:CMS垃圾回收器并行线程线,推荐值为CPU核心数。
- -XX:
- ParallelGCThreads=8:新生代并行收集器的线程数。
- -XX:
- MaxTenuringThreshold=10:**设置垃圾最大年龄。**如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
- -XX:
- CMSFullGCsBeforeCompaction=4:指定进行多少次fullGC之后,进行tenured区 内存空间压缩。
- -XX:
- CMSMaxAbortablePrecleanTime=500:当abortable-preclean预清理阶段执行达到这个时间时就会结束。?????
遇到宕机等生产事故的时候,解决问题都不是通过一个日志来处理的,需要通过dump日志,gc日志还有jstack日志进行综合分析,才能更快的定位,解决问题
本人遇到的实际问题:
-XX:MetaspaceSize=1024m? 我们测试环境没有去设置这个参数配置,那默认就是21MB,21MB对于我们的系统来说是远远不够的,导致我们的测试环境老是突然挂掉,通过配置
export JAVA_OPTS="-Xms10240m -Xmx10240m -Xss2048K -XX:MetaspaceSize=1024m ?-Dcheck.global=true -Dhsts.filter=true
-DX-Frame-Options=true
-Dsecurity.disable=true
-Dfastjson.parser.safeMode=true -verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps -Xloggc:/opt/app/applogs/gc.log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/app/applogs/68dump.hprof"
打印gc日志,发现短时间内发生了八次full GC??
原因是因为-XX:MetaspaceSize=1024m 没配置,元空间的内存不足,导致一直fullGc
课外知识:
- JDK1.7 有永久代,字符串常量池,静态变量移除,保存在堆中 其他的常量池存放在永久代
- JDK1.8 无永久代,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池、静态变量仍然在堆中。
永久代为什么要被元空间替代?
只有Hotspot才有永久代。BEA JRockit、IBMJ9等来说,是不存在永久代的概念的
1.JDK8 开始 无永久代改为元空间,分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间;
2.为永久代设置空间大小是很难确定的,在某些场景下,如果动态加载类过多,容易产生方法区的OOM。比如某个实际Web工程中,因为功能点比较多,需要加载的类很多,在运行过程中,要不断动态加载很多类,经常出现致命错误。 java.lang.OutOfMemoryError:PermGen space
3.而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。
总结:
- 没有设置元空间大小,默认了初始值,导致频繁fullGC,测试环境在启服务的时候每次都很慢
- 新生代空间越大,Minor GC的GC时间越长,频率越低。如果想减少其持续时长,就需要减少其空间大小
- ?jmap -dump:format=b,file=xxx pid,可以生成堆信息的文件,但是这个命令不建议在生产环境使用,因为当内存较大时,执行该命令会占用大量系统资源,甚至造成卡顿。建议在项目启动时添加下面的命令,在发生oom时自动生成堆信息文件:-XX:+HeapDumpOnOutOfMemory。