jvm相关总结

jvm常用参数

 
-XX:+PrintGCDetails -XX:+PrintGC -XX:+PrintGCTimeStamps -Xloggc:file -XX:+PrintHeapAtGC
-XX:+HeapDumpOnOutOfMemoryError   -XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath
-Xmx100m -Xms100m -Xmn50m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=64m
-XX:NewRatio=10 -XX:SurvivorRatio=2
-XX:+DisableExplicitGC
-XX:MaxDirectMemorySize
-Xss
 
GC情况:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT: Full GC次数和Full GC耗时(不一定是FGC,也可能是CMS GC)
GCT:GC总耗时<br><br>
 
jstat -gcutil [pid] 60000   查看GC情况
jmap -histo :live [pid]     会(也可用于)强制 fullgc  生成文本文件 jmap -dump:live,format=b,file=heap.bin <pid>产生gc收不走的对象
jmap -histo 12309
jmap -dump:format=b,file=文件名 [pid]   不导致fullgc  jmap -dump :live  会导致
jmap -heap pid    查看整个JVM内存状态 
jinfo -flags process_id
jhat -J-Xmx1024M [file]     java自带分析dump文件工具,优点:不用把dump文件down下来,缺点:占内存
-XX:+HeapDumpBeforeFullGC
 
总流程:
越跑越慢/内存溢出
  jstat查看fgc频率(fgc!=full gc)
    jmap -histo[:live] <pid>           打印当前java堆中各个对象的数量、大小
    jmap -dump:[live,]format=b,file=<filename> <pid>     把java堆中的对象dump到本地文件,然后分析
      jhat            在线原位
      visualvm    需下载
      mat            需下载
               HeapDumpBeforeFullGC
几个案例:ArrayBlockingQueue,Druid.JdbcSqlStat,jstack线程显式gc,线程池拒绝又放入无限循环栈溢出
 
经验:
如果full gc过于频繁,经查内存未满即fgc了,则基本是显式gc
full gc过于频繁,每次回收前后空间又降不下去,说明有大对象顽固分子进驻回收不掉,要看对象了
full gc过于频繁,每次空间回收也合理,那么就结合youngc晋级对象、dump和代码审查
每次youngc后,堆总大小理想中不应增加,如果增加太多,要警惕,说明有对象晋级或大对象,最好看对象,而且总有一天会引发fullgc频繁
younggc不频繁,建议缩小内存,节约服务器资源
younggc太频繁,看新生代大小和eden区大小
建议 young:old = 4:6 ; eden:s0:s1 = 8:1:1
 
目标:
YoungGC频率不超过2秒/次;
CMS GC频率不超过1天/次;
每次YoungGC的时间不超过15ms;
FullGC频率尽可能完全杜绝;(jstat中的FGC不准确,有可能是cms gc-每次+2fgc,准确看gc日志)

 

 

https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247484458&idx=1&sn=09ab6cd3b4187df5bc6e693df57778d5&chksm=96cd4466a1bacd70262a232cf1ae091b528912630a4cb8686c33259b5ca9289e1afc7f334b03&mpshare=1&scene=1&srcid=0818yNvC8sScLesR7jjUdD2X&key=aabb2ccd6a6552351166d5ae3fae009e9ce42be9ad0443233aeef7716871ffa9e9ba6de8ec069a4426ff522833b46ed9fe262772735d065a62d5de188237e8e4172f8e848c350c13c3d4e5d56be9fe7e&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=5aXt5uXOGcgIC7KGUdIaSeIlAcbxVAg2lZI0X5mZh1cMsn46Qh5h0z4PnhyEs5Di

 

GC主要有YoungGC,OldGC,FullGC(还有G1中独有的Mixed GC,收集整个young区以及部分Old区,提及的概率相对少很多,本篇文章不打算讲解)

截止Java发展到现在JDK9为止,只单独回收Old区的只有CMS GC

对于ParallelOldGC即默认GC在Old满了以后触发的FullGC是没有问题的,jstat命令查看输出结果FGC的值也会相应的+1,即发生了一次FGC。FGC误解主要来自最常用的ParNew+CMS组合很多人误解FullGC可能是受到jstat命令结果的影响,因为发生CMS GC时,FGC也会增大(但是会+2,这是因为CMS GC的初始化标记和重新标记都会完全的STW,从而FGC的值会+2)。但是,事实上这并没有发生FullGC。jstat命令结果中的FGC并不表示就一定发生了FullGC,很有可能只是发生了CMS GC而已。事实上,FullGC的触发条件非常苛刻,判断是否发生了FullGC最好的方法是通过GC日志,日志中如果有"full gc"的字样,就表示一定发生了Full GC。所以强烈建议生产环境开启GC日志,它的价值远大于它对性能的影响(不用权衡这个影响有多大,开启就对了)。

 

G1或者ParNew+CMS组合前提下,如果真的发生FullGC,则是单线程完全STW的回收方式(SerialGC)退化为单线程,可以想象性能有多差,如果是es,hbase等需要几十个G的堆,那更是灾难。

 

注意:Paralled Scavenge是否是并行/并发的未知

 

  • 对象优先在Eden分配。如果新生代放不下对象的时候,object会直接被放到老年代中。
  • 大对象直接进入老年代。
  • 长期存活的对象将进入老年代。一般情况下接受过15次Minor GC后晋升老年代 XX:MaxTenuringThreshold可设置
  • survivor 的“to”区满了之后(并非survivor2片都满,survivor永远有1个-from区是空的),对象进到old区

转载于:https://www.cnblogs.com/silyvin/p/9844445.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值