内存泄露&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高的线程。

​Arthas性能测试调优实践

3、 执行Thread -n 3命令将占用资源最高的前三个线程的堆栈信息打印出来,通过这三个线程的堆栈信息得到,代码中某类的diedCycle()方法占用CPU资源较高

​Arthas性能测试调优实践

4、 执行jad命令对某类进行反编译,得到出现问题的源代码,通过代码分析,发现这段代码死循环一直占用系统资源,在使用过程中并没有释放这些资源,最终导致服务器CPU利用率100%。

​Arthas性能测试调优实践

​Arthas性能测试调优实践

解决方法:删除diedCycle()方法,经验证,问题解决。

 

性能问题二

问题描述:在稳定性测试过程中,通过查看应用日志发现OutOfMemoryError”报错信息。如下图

​Arthas性能测试调优实践

问题分析:经分析,jvm内存不足,程序代码HashMap或ArrayList对象某代码出现书写缺陷。

问题挖掘过程:

1、启动arthas,执行dashboard查看堆内存和GC使用情况。发现程序持续产生多次FULL GC,且每次FULL GC后并没有清理出垃圾对象,导致老年代的堆内存持续增高。

​Arthas性能测试调优实践

​Arthas性能测试调优实践

2、执行heapdump生成堆存储文件

​Arthas性能测试调优实践

3、对dump文件进行分析,发现main()异常线程 

4、执行Jad命令查看源代码,程序不断的生成字节数组,并将字节数组存储到list容器中死循环导致list容器占用的堆内存持续增长,最终导致无堆内存可用报错OutOfMemoryError 

​Arthas性能测试调优实践

解决办法:对main()函数进行优化。经验证,问题解决。

本次性能调优采用阿里开源的Arthas工具进行监控的,它是一款开源在线Java诊断工具,采用命令行交互模式,支持Linux /Windows,同时提供丰富的Tab自动补全功能方便进行问题的定位和诊断

​Arthas性能测试调优实践

 

Arthas是一个java程序通过命令java -jar arthas-boot.jar启动。

​Arthas性能测试调优实践

举例:

输入dashboard指令进入系统性能全局监控,显示当前系统的实时数据面板(线程、内存、GC、运行信息

以上是关于内存泄露&arthas的主要内容,如果未能解决你的问题,请参考以下文章

内存溢出&内存泄露

Android性能优化:手把手带你全面了解 内存泄露 & 解决方案

Android性能优化:手把手带你全面了解 内存泄露 & 解决方案

Android性能优化:阿里腾讯等关于内存泄露的知识都在这里了!

Android 常见内存泄露 & 解决方案

Android :安卓学习笔记之事件内存泄露 的简单理解