VisualVM 分析full GC问题记录
背景:JAVA APP,主要功能是处理日志并存入db
现象:运行一段时间就出现OOM问题,查看GC log发现运行没多久就一直Full GC,并且抛出OOM的异常。
[Full GC (Ergonomics) [PSYoungGen: 529920K->525999K(614912K)] [ParOldGen: 1398052K->1397869K(1398272K)] 1927972K->1923868K(2013184K), [Metaspace: 33827K->33827K(1079296K)], 4.1812153 secs] [Times: user=32.38 sys=0.07, real=4.19 secs]
[Full GC (Ergonomics) [PSYoungGen: 529920K->525483K(614912K)] [ParOldGen: 1397869K->1397848K(1398272K)] 1927789K->1923331K(2013184K), [Metaspace: 33832K->33832K(1079296K)], 5.6714054 secs] [Times: user=43.50 sys=0.09, real=5.67 secs]
GC日志中老年代非常大,而且回收效果也不明显。遇到这种问题,第一感觉还是有内存泄露,虽然Java能自己回收内存,但是不能保证我自己写的程序没有问题,比如曾经犯过一个错误往list一直add object,却没有remove,并且list也不释放,导致list越来越大,最后内存OOM。本着大胆假设,小心求证的理念,开始排查问题。
遇到内存问题,最好是希望能够直观的看到Java程序堆中现在有哪些对象,有哪些对象数目一直在递增而没有被回收。为此需要借助工具来排查了,visualVM是非常好的能满足需求的一个工具。
启动visualVM,启动程序,通过Visual GC查看内存情况。

从上图中,我们很明显发现程序的Old Generation占用空间是在不断地上涨,并且没有明显下跌,说明生成的对象都是存在内存里面的,并没有被释放掉。接下来查看一下内存中有哪些对象

使用Sampler标签页中的Memory 采集功能,查看内存中当前是哪些对象,从采样结果来看Request对象是非常多的,而且一直在递增。Request对象在程序中使用较多,接下来看下是哪个线程一直在积压Request

查看Per thread allocations,很容易看出insertRequestList线程分配的内存最多。
对照程序我恍然大悟,发现问题就出在插入数据上。程序中插入数据库采用异步批量插入方式,当生成一个Request对象就存入一个LinkedBlockingQueue,集满一定量进行批量插入。而我设置的LinkedBlockingQueue初始化了一个非常大的capacity,这就导致来不及插入的Request全部都堆积在LinkedBlockingQueue中了。
临时解决方案:将LinkedBlockingQueue的capacity设置小一些,并且采用put方式插入Request到LinkedBlockingQueue,当插入来不及的时候就等待。
修改代码后再来看下visualVM结果:

old Generation每次GC能回收大量的Object,不会出现Full GC了。


Request对象数量也并不是一直在增长了。但是InsertRequestThread线程仍然是分配了很多的内存,可以得知该线程必然还是积压了大量的Request对象的。因为只采用了临时解决方案,mysql插入数据速度上不去,积压在所难免。
附录:
visualVM远程监控
在执行Java 应用程序的服务器上先生成一个jstatd.all.policy
grant codebase "file:${JAVA_HOME}/lib/tools.jar" {
permission java.security.AllPermission;
};
然后执行命令
nohup ${JAVA_HOME}/bin/jstatd -J-Djava.rmi.server.hostname=10.111.123.234 -J-Djava.security.policy=jstatd.all.policy -J-Dcom.sun.management.jmxremote.authenticate=false -J-Dcom.sun.management.jmxremote.ssl=false -J-Dcom.sun.management.jmxremote.port=8888 &
然后在本地启动visualVM,Remote添加10.111.123.234,默认端口1099就可以监控服务器上的程序运行状况了,非常方便。
如果出现access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write")报警,则建议将$JAVA_HOME和jstatd.all.policy都使用绝对路径。
VisualVM 分析full GC问题记录的更多相关文章
- JVM诊断及工具笔记(4) 使用visualvm分析JVM堆内存泄漏
在这里感谢最近一直阅读我文章的小伙伴,如果觉得文章对你有用,可以帮忙关注转载,需要的时候可以及时找到文章. 背景 今年Q3季度我们在推广业务方使用Iceberg,当时为了让不同业务线的用户可以使用自己 ...
- Java程序性能分析工具Java VisualVM(Visual GC)—程序员必备利器
VisualVM 是一款免费的\集成了多个JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回收 ...
- 源码分析HotSpot GC过程(三):TenuredGeneration的GC过程
老年代TenuredGeneration所使用的垃圾回收算法是标记-压缩-清理算法.在回收阶段,将标记对象越过堆的空闲区移动到堆的另一端,所有被移动的对象的引用也会被更新指向新的位置.看起来像是把杂陈 ...
- VisualVM分析与HelloWorld、springBoot项目
VisualVM分析与HelloWorld.springBoot项目 自从1995年第一个JDK版本JDKBeta发布,至今已经快25年,这些年来Java的框架日新月异,从最开始的Servlet阶段, ...
- 源码分析HotSpot GC过程(一)
«上一篇:源码分析HotSpot GC过程(一)»下一篇:源码分析HotSpot GC过程(三):TenuredGeneration的GC过程 https://blogs.msdn.microsoft ...
- 使用Anemometer分析MySQL慢查询记录
数据库管理员一般是用percona的toolkit工具来分析MySQL慢查询记录,但是不够直观. 下面介绍一款比较直观的工具来统计分析MySQL慢查询记录anemometer. 在使用之前需要安装pe ...
- 使用VisualVM分析性能
性能分析神器VisualVM VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量 ...
- 基于binlog来分析mysql的行记录修改情况(python脚本分析)
最近写完mysql flashback,突然发现还有有这种使用场景:有些情况下,可能会统计在某个时间段内,MySQL修改了多少数据量?发生了多少事务?主要是哪些表格发生变动?变动的数量是怎 ...
- GC知识记录
2.关于Minor GC,Major GC与Full GC 1) Minor GC:即新生代的GC,指发生在新生代的垃圾收集动作.当新生代的Eden区内存不足时,就会触发Minor GC.由于对象创 ...
随机推荐
- Azure 基础 : 使用 Automation 定时开机
不知何时 Azure 为虚机提供了自动关机的功能.这是一个很棒的功能,可以帮助我们定时关闭虚机并释放掉资源以节省开支.如果某台虚机在夜间不需要提供服务,我们就可以把它配置为晚上的某个时间点自动关机: ...
- Python随笔------初探
今年的双十一刚刚才过去,大多数人主要就是抢购商品,可能他们现在已经收到了他们夜以继日抢购的商品.然而对于我们做技术的,特别是做互联网技术的,我相信肯定都被双十一那天的许多技术震撼到了吧.云计算.分压式 ...
- java 之 抽象工厂模式(大话设计模式)
看了几次抽象工厂模式,每次查看都需要重新理解一次,可能是涉及的类和接口比较多,所以比较难缕清的关系吧!在笔者看来,我们还是要吸取其思想而不是生搬硬套. 来看下类图: 大话设计模式-类图 看类图已经很乱 ...
- 【转】如何使用Git上传本地项目到github?(mac版)
原文链接:http://www.cnblogs.com/lijiayi/p/pushtogithub.html 在此假设你已经在 github 上创建好了一个项目,像这样: 并且你已经完成了自己的项目 ...
- 实践作业1:测试管理工具实践 Day3
1.Vertrigoserv启动后,首先要配置apache,则需要修改监听端口,不要出现端口冲突2.配置mysql,在mysql console中输入密码vertrigo3.在浏览器中输入http:/ ...
- 数据库服务器---Tps
事务处理系统:Transactionprocessingsystems(TPS) 提高事务处理效率与保证其正确性 在数据(信息)发生处将它们记录下来 通过OLTP产生新的信息 将信息保存到数据库中供其 ...
- MongoDb安装--yum安装
本帖最后由 草包 于 2017-5-2 09:57 编辑 [Shell] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 ...
- PHP数组实际占用内存大小的分析
一般来说,PHP数组的内存利用率只有 1/10, 也就是说,一个在C语言里面100M 内存的数组,在PHP里面就要1G.下面我们可以粗略的估算PHP数组占用内存的大小,首先我们测试1000个元素的整数 ...
- 【垃圾回收】Java内存回收实践经验 防止内存报警
jdk6和7服务器端(-server) 默认的新生代的垃圾回收器为:PS Scavenge,老年代默认的垃圾回收器为:PS MarkSweep 目前项目使用了jdk7,tomcat7,经常出现内存堆使 ...
- Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长
Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...