一次Jvm old过高的排查过程实战记录

 更新时间:2018-11-05 17:00:29   作者:佚名   我要评论(0)

前言
最近遇到一个Jvm old过高的案例,现象是一个站点的jvm old区过高,分析原因是,原来的设计方案有问题,给前端返回的数据里面包含了大量的html代码,从存

前言

最近遇到一个Jvm old过高的案例,现象是一个站点的jvm old区过高,分析原因是,原来的设计方案有问题,给前端返回的数据里面包含了大量的html代码,从存储中拿数据的过程、拼接数据的过程过于漫长了,造成了大量对象的生命周期过长,对象被 标记到了old中,造成了old区过高,监控系统进行了报警,详细原因就不做详细分析了,主要分享一下问题排查的过程。

收到了监控系统的报警,在服务器上查询jvm内存情况

jstat -gcutil pid 时间间隔,可以按时间间隔打印jvm的内存情况,例如:

jstat -gcutil 30922 1000

jvm进程30922的内存情况

大致说一下,S0,S1这些的含义:

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E: 年轻代中Eden(伊甸园)已使用的占当前容量百分比
O: old代已使用的占当前容量百分比
P: perm代已使用的占当前容量百分比
YGC: 从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC: 从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT: 从应用程序启动到采样时gc用的总时间(s)

从内存情况,来看,S0、伊甸园已经被打满,old已经被打满,排除了是大对象实例过多直接把old打满的情况,继续分析

查看应用启动的jvm参数

-Xms2g -Xmx2g -Xmn1g -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=10 -XX:CMSInitiatingOccupancyFraction=80

说两个参数的含义吧

XX:SurvivorRatio=4,这个参数的意思是Survivor两个区与新生代的比例,设置为4的意思是两个区与新生代的比例为2:4,MaxTenuringThreshold=10, 这个参数的意思是对象标记多少次后记为old对象,放入到老年代中,设置为10就是新生代对象被标记10次还没有释放,就放到老年代中,从参数上看,造成old区过高报警的原因是有的对象在新生代中,被标记了10次都没有被释放,被放入到了老年代中,造成了老年代过大,FGC频率过高

经朋友指点,这一块的分析有问题,有问题的分析留着,再贴一下朋友的分析,对比一下

动态对象年龄判定:为了能更好地适应不同程度的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升到老年代,如果在Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄


朋友的指导

导出dump文件,使用jvisualvm.exe查看

导出dump文件的过程就不赘述了,简单贴一下命令

jmap -dump:format=b,file=serviceDump.dat pid

jvisualvm是一个jdk自带的内存分析工具,一般位置在jdk安装目录下:

C:\Program Files\Java\jdk1.8.0_141\bin\jvisualvm.exe

jvisualvm工具界面

在这选择已经导出的dump文件,查看内存中类的实例数、实例大小


查看类的实例数

发现是Char[],String,HashMap这三个的实例是jvm中最多的,实例数分别占31%、30.9%、30.2%,总共占了92.1%,实例的大小分别占35.8%、14.6%、22.4%,总共占了72.8%,主要是这三个类的实例占用过大的内存

查看Char[]的实例信息

点击去,查看Char[]的实例信息,从大到小的排列


有一些实例比别的实例大很多

查看最大的这些实例,发现这些实例里面的内容是

<graph lineThickness='3' showValues='0' formatNumberScale='1' anchorRadius='3' divLineAlpha='20' divLineColor='CC3300' divLineIsDashed='1' showAlternateHGridColor='1' alternateHGridAlpha='5' alternateHGridColor='CC3300' shaowAlpha='40d' chartRightMargin='3..

目测这些都是前端使用的图表所用到的数据,设计不合理,这些图表的html代码由后台代码给前端返回了


实例里面的内容

查看这些实例的堆栈信息

查看这些实例的垃圾回收根节点


查看这些实例的垃圾回收根节点

发现是根节点是 StringBuilder对象,查看堆栈信息


查看堆栈信息

堆栈信息

通过堆栈信息,就定位到了代码中,分析代码,原因基本是,原来的设计方案有问题,给前端返回的数据里面包含了大量的html代码,从存储中拿数据的过程、拼接数据的过程过于漫长了,造成了大量对象的生命周期过长,对象被 标记到了old中,造成了old区过高,这里就是是分享下,排查的过程,不对原因过于详细的表述了

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

您可能感兴趣的文章:

  • Java虚拟机JVM性能优化(一):JVM知识总结
  • JVM的垃圾回收机制详解和调优
  • 基于JVM 调优的技巧总结分析
  • 简单谈谈JVM、JRE和JDK的区别与联系

相关文章

  • 一次Jvm old过高的排查过程实战记录

    一次Jvm old过高的排查过程实战记录

    前言 最近遇到一个Jvm old过高的案例,现象是一个站点的jvm old区过高,分析原因是,原来的设计方案有问题,给前端返回的数据里面包含了大量的html代码,从存
    2018-11-05
  • 易语言将数值转换为人民币金额的简体或繁体大写形式

    易语言将数值转换为人民币金额的简体或繁体大写形式

    数值到金额命令 英文命令:NumToRMB 操作系统支持:Windows、Linux 所属类别:数值转换 将数值转换为金额的简体或繁体大写形式,返回转换后的文本。 语法
    2018-11-05
  • 易语言从前或从后寻找指定字节集

    易语言从前或从后寻找指定字节集

    这个功能要用到以下几个命令: 寻找字节集命令 倒找字节集命令 语法: 整数型 寻/倒找字节集 (被搜寻的字节集,欲寻找的字节集,[起始搜寻位置])
    2018-11-05
  • 易语言将数值转换为指定格式的文本

    易语言将数值转换为指定格式的文本

    数值到格式文本命令 英文命令:NumToText 操作系统支持:Windows、Linux 所属类别:数值转换 返回一个文本,代表指定数值被格式转换后的结果。 语法: 文
    2018-11-05
  • 易语言将其它类型的数据转换为双精度小数型

    易语言将其它类型的数据转换为双精度小数型

    到数值命令 英文命令:val 操作系统支持:Windows、Linux 所属类别:数值转换 返回包含于文本内的数值,文本中是一个适当类型的数值,支持全角书写方式。
    2018-11-05
  • 利用hasOwnProperty给数组去重的面试题分享

    利用hasOwnProperty给数组去重的面试题分享

    hasOwnProperty hasOwnProperty是javascript中用于检测对象是否包含某个属性的方法,返回一个布尔值。 var o = { a: 1}; console.log(o.hasOwnProperty(
    2018-11-05
  • c#和java base64不一致的解决方法

    c#和java base64不一致的解决方法

    本文主要介绍了关于c#和java base64不一致的解决方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 不一致的问题不是编码的问题 而是j
    2018-11-05
  • 易语言将十进制数值转换为十六进制文本的方法

    易语言将十进制数值转换为十六进制文本的方法

    取十六进制文本命令 英文命令:hex 操作系统支持:Windows、Linux 所属类别:数值转换 返回一个文本,代表指定数值的十六进制形式。 语法: 文本型 取十
    2018-11-05
  • 易语言将数值转换为简体或繁体的大写形式

    易语言将数值转换为简体或繁体的大写形式

    数值到大写命令 英文命令:UNum 操作系统支持:Windows、Linux 所属类别:数值转换 将数值转换为简体或繁体的大写形式,返回转换后的文本。 语法: 文本
    2018-11-05
  • 浅谈Asp.Net母版页的相关知识

    浅谈Asp.Net母版页的相关知识

    Asp.Net母版页的相关知识 母版页的使用与普通页面类似,可以在其中放置文件或者图形、任何的HTML控件和Web控件,后置代码等。母版页的扩展名以.master结尾,不
    2018-11-05

最新评论