内存泄露&arthas
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄露&arthas相关的知识,希望对你有一定的参考价值。
参考技术A 导出超过20W条数据到excel。默认使用poi提供方法XssfWorkBook进行写入Excel。
分页查询数据,每次查询完之后,写入到Excel。
在写入数据10W+的时候,用时2分钟左右;
但10W+之后,速度开始慢了下,导出20W数据大约需要30分钟左右;多次导出之后,出现内存溢出问题。
怀疑sql查询太慢,超过10W条数据可能出现了深度翻页的问题。
但是通过增加日志,打印执行时间,发现用时并没有太久(同时,sql查询也有超时时间,超过5s左右会终止查询,抛出异常,而这种情况并没有出现)。
怀疑可能是Excel文件太大了,后面写入会增加时间,导致速度慢下来了。但是通过增加打印日志,发现耗时基本是可以忽略的。
在导出过程中,页面进行其他操作,接口出现超时。怀疑是jvm在做full gc,出现了“Stop The World”情况。
通过arthas 监控内存,以及通过jmap -histo 命令观察gc情况,发现事实是这样,执行full gc的次数很频繁,而且每次执行完full gc之后,堆内存的情况并没有很明显的减少,导致出现了频发full gc的情况。
通过jmap -heap 命令查看内存分布情况,发现排名靠前的对象有类似dom4j的东西,所以怀疑是写入Excel导致内存泄露。
解决方法:SXssfWorkBook替换XssfWorkBook。问题解决。
- arthas
- jmap -histo [pid] [interval]
- jmap -heap >> test.txt
在线上环境,偶尔会收到报警调用ES超时;
一般情况下都是ES所在的机器jvm发生full gc;
导致full gc的原因:某个商家做活动,一段时间内涌入了大量的流量,导致ES内存增长很快,所以产生了full gc。在full gc的时间段内,对外基本不提供服务,接口超时。
当前系统的实时数据面板
线程信息(部分)、内存、GC次数、GC时间、基本信息
显示线程信息
thread -n 指定最忙的前N个线程并打印堆栈
jvm的配置信息
打印类的详细信息
打印类中详细信息以及变量信息
查看已加载类的方法信息
查看方法的详细信息
非实时返回
-c :统计周期,默认为120秒
timestamp 时间戳
class java类
mehtod 方法(构造方法、普通方法)
total 调用次数
success 成功次数
fail 失败次数
rt 平均rt
fail-rate 失败率
monitor class-pattern method pattern
方法内部调用路径,并输出方法路径上的每个节点的耗时
trace class-pattern method-pattern -n #cost
trace *StringUtils isBlacnk '$cost>100'
查看某个方法的调用路径-堆栈信息
grovy 表达式
watch com.example.demo.arthas.ArthasInnerService test2 "params.length,params[0],returnObj.age" returnObj.books.size()>4
Arthas性能测试调优实践
近期,在对某Java类应用系统性能测试时,发现应用服务器CPU利用率接近100%,并且系统长时间运行还存在内存泄露的情况,我们利用Arthas工具进行了问题代码定位分析,达到了较好的优化效果,过程如下:
性能问题一
问题描述:在混合压力测试场景中,发现应用服务器CPU使用率接近100%。
问题分析:通过TOP查看进程CPU利用率,发现java进程占CPU较高。经分析,Java应用程序中某代码模块存在性能问题。
问题挖掘过程:
1、 查看Java进程id,记录PID为6193
2、 启动arthas,对6193进程进行跟踪,执行dashboard命令查看占用CPU高的线程。
3、 执行Thread -n 3命令将占用资源最高的前三个线程的堆栈信息打印出来,通过这三个线程的堆栈信息得到,代码中某类的diedCycle()方法占用CPU资源较高。
4、 执行jad命令对某类进行反编译,得到出现问题的源代码,通过代码分析,发现这段代码死循环一直占用系统资源,在使用过程中并没有释放这些资源,最终导致服务器CPU利用率100%。
解决方法:删除diedCycle()方法,经验证,问题解决。
性能问题二
问题描述:在稳定性测试过程中,通过查看应用日志发现“OutOfMemoryError”报错信息。如下图
问题分析:经分析,jvm内存不足,程序代码HashMap或ArrayList对象某代码出现书写缺陷。
问题挖掘过程:
1、启动arthas,执行dashboard查看堆内存和GC使用情况。发现程序持续产生多次FULL GC,且每次FULL GC后并没有清理出垃圾对象,导致老年代的堆内存持续增高。
2、执行heapdump生成堆存储文件
3、对dump文件进行分析,发现main()异常线程
4、执行Jad命令查看源代码,程序不断的生成字节数组,并将字节数组存储到list容器中,死循环导致list容器占用的堆内存持续增长,最终导致无堆内存可用报错OutOfMemoryError。
解决办法:对main()函数进行优化。经验证,问题解决。
本次性能调优采用阿里开源的Arthas工具进行监控的,它是一款开源在线Java诊断工具,采用命令行交互模式,支持Linux /Windows,同时提供丰富的Tab自动补全功能,方便进行问题的定位和诊断。
Arthas是一个java程序,通过命令java -jar arthas-boot.jar启动。
举例:
输入dashboard指令进入系统性能全局监控,显示当前系统的实时数据面板(线程、内存、GC、运行信息)
以上是关于内存泄露&arthas的主要内容,如果未能解决你的问题,请参考以下文章
Android性能优化:手把手带你全面了解 内存泄露 & 解决方案
Android性能优化:手把手带你全面了解 内存泄露 & 解决方案