java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java的内存溢出

java中的内存溢出方式

作者:子裳

文章介绍了如何使用jmap和IBMHeapAnalyzer等工具分析OutOfMemoryError: Compressedclassspace错误,发现问题出在/org/pf4j/PluginClassLoader加载了大量类

问题

kettle数据采集系统崩溃-查看报错信息为:

OutOfMemoryError: Compressed class space

可以看到是内存溢出,但是可以看到的后面的信息为 Compressed class space ,而不是java heap。

Compressed class space为压缩类空间, 这个空间是保存在64位系统中类引用地址的空间,默认大小为1G,单个类引用地址的空间是1K

意味着加载的类已经超过1百万,这肯定是存在问题的,需要进一步查找问题。

内存dump

将系统当时的内存情况dump下来进行分析

jmap

java自带visualVM,jmap等分析工具可以直接使用 

将当前系统活跃的内存数据写入到kettle-test-dump-03020941.hprof 文件中,系统pid为18090

jmap -dump:live,format=b,file=./kettle-test-dump-03020941.hprof 18090

在实际使用时,发现jdk是openjdk,并未自带jmap等工具,可以进行升级.但是怕影响系统运行,另外下载了一个jdk使用

分析

使用工具进行分析,下面介绍两种工具进行查看,java自带的jvisualVM和IBM HeapAnalyzer: 

jvisualVM不需要下载,但是不会自行统计,需要自己写sql来进行深度分析 

IBM HeapAnalyzer提供表格,饼图的方式,更加直观的看到数据,并且会分析出最可能发生内存泄漏的地方

jvisualVM

使用本地jdk自带的visualVM来进行分析查看

1.下载hprof文件到本地

2.找到jdk目录,找到 bin/jvisualvm.exe ,双击打开,界面如下:

3.导入文件 点击 文件->装入->切换到dump文件 ->找到hprof文件打开

4.点开类视图,过滤出classload ,并根据classload 找到对应的示例和加载类的个数,数据不太直观,但是统计后可以看出问题出在/org/pf4j/PluginClassLoader,根据此信息查找bug出现的原因。

IBM HeapAnalyzer

本来想使用MAT,但是官网的下载太慢等不起,正好同事安利,就使用了这个:IBM HeapAnalyzer 

1.下载hprof文件到本地

2.打开程序 找到ha457.jar包目录

java -jar ha457.jar

打开后可以看到以下界面

3.打开下载的文件

4.查找类加载项

上图中有三个表格,第一个是加载器类型表格(包括加载器类型,加载器实例数,加载器加载的类的数量),第二个表格是单种加载器的每个实例,以及加载的数量,第三个是每个加载器实例加载的类 

可以看到 /org/pf4j/PluginClassLoader 的加载器实例有1千多个,类加载有17万个,大概可以判定是异常数据。等待一段时间后再dump下内存,发现加载的类达到30几万,判断内存溢出就是由这个加载器不断加载类却不释放导致。 

根据第三个表格可以找到对应的类,查找到具体原因。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文