【JVM调优】JVM 参数说明 与 《元空间》

  • -XX:+HeapDumpOnOutOfMemoryError 
    • dump堆内存溢出信息
  • XX:HeapDumpPath=/opt/app/applogs/68dump.hprof"
    • dump文件存储路径
  • -Xloggc:  /opt/app/applogs/gc.log
    • 打印gc日志,指定路径   
  • -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

课外知识:

  1. JDK1.7 有永久代,字符串常量池,静态变量移除,保存在堆中 其他的常量池存放在永久代
  2. JDK1.8 无永久代,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池、静态变量仍然在堆中。

永久代为什么要被元空间替代?


只有Hotspot才有永久代。BEA JRockit、IBMJ9等来说,是不存在永久代的概念的

1.JDK8 开始 无永久代改为元空间,分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间;

2.为永久代设置空间大小是很难确定的,在某些场景下,如果动态加载类过多,容易产生方法区的OOM。比如某个实际Web工程中,因为功能点比较多,需要加载的类很多,在运行过程中,要不断动态加载很多类,经常出现致命错误。 java.lang.OutOfMemoryError:PermGen space

3.而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

总结:

  1. 没有设置元空间大小,默认了初始值,导致频繁fullGC,测试环境在启服务的时候每次都很慢
  2. 新生代空间越大,Minor GC的GC时间越长,频率越低。如果想减少其持续时长,就需要减少其空间大小
  3.  jmap -dump:format=b,file=xxx pid,可以生成堆信息的文件,但是这个命令不建议在生产环境使用,因为当内存较大时,执行该命令会占用大量系统资源,甚至造成卡顿。建议在项目启动时添加下面的命令,在发生oom时自动生成堆信息文件:-XX:+HeapDumpOnOutOfMemory。

FULL GC 解析

  • 根据服务器的物理内存或虚拟机的限制来设置-Xmx和-Xms参数。通常,建议将-Xmx设置为系统总内存的60%-80%。

  • 如果您的应用程序需要大量的永久代空间(PermGen),请根据需要调整-XX:MaxPermSize(适用于Java 7及更早版本)。对于Java 8及更高版本,请使用-XX:MaxMetaspaceSize。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值