4年前 (2021-01-19)  jvm |   抢沙发  1243 
文章评分 0 次,平均分 0.0

本文将简单介绍工具Eclipse Memory Analyzer以及如何使用此工具查找一些内存问题。

一. 将内存分析器安装到Eclipse中

启动更新管理通过帮助→软件更新…

选择“可用软件”选项卡并添加内存分析器更新站点:http://download.eclipse.org/technology/mat/0.7/update-site/

选择内存分析器功能。点击“安装”按钮进行安装。

接受许可证并重新启动Eclipse(也可以作为单独的软件直接使用)

二. 从JVM虚拟机获取堆转储dump文件

内存分析器可以处理HPROF二进制格式的堆转储。这些堆转储由Sun HotSpot和从HotSpot派生的任何VM编写。根据您的场景、操作系统平台和JDK版本,您可以使用不同的选项来获取堆转储。

Vendor / Release -XX:+HeapDumpOnOutOfMemoryError writes heap dump on OutOfMemoryError -XX:+HeapDumpOnCtrlBreak writes heap dump together with thread dump on CTRL+BREAK Sun JMap: jmap.exe -dump:format=b,file=HeapDump.hprof Sun JConsole: Launch jconsole.exe and invoke operation dumpHeap() on HotSpotDiagnostic MBean
1.4.2_12 Yes Yes No No
1.5.0_07 Yes No Yes(Only Solaris and Linux) No
1.6.0_00 Yes No Yes Yes

一般情况下,堆转储dump文件将生成为java_pid3524.hprof

三. 查找内存泄漏的最简单方法

Eclipse菜单窗口→打开透视图→内存分析器

Eclipse菜单文件→打开堆转储=>选择hprof文件,如java_pid3524.hprof

将显示概览图:

如何使用Eclipse内存分析器分析内存泄漏

单击“Leak Suspects”报告链接

如何使用Eclipse内存分析器分析内存泄漏

单击问题 Suspect 1 Details 链接

如何使用Eclipse内存分析器分析内存泄漏

然后你会看到:

Class name Shallow Heap Retained Heap Percentage
java.lang.Object@ 0×23d04040 9,047,792 273,923,024 97.00%
com.starcite.commonsearch.client.vendor.impl.VendorImpl @ 0×16b80000 135 136 0.00%

所以java.lang.Object2261945@0×23d04040“大约需要9M的浅堆(这意味着直接引用的内存)和273m的保留堆(这意味着直接引用或不直接引用的所有内存)。现在,我们可以知道这是内存泄漏的根本原因

那么,接下来呢?当然,下一步是找出导致此问题的代码?

然而,这不是一件容易的事。你现在必须利用你的经验。

有什么信息可以作为出发点吗?您可以找到以下信息-

Accumulated Objects "堆积物"

Class name Shallow Heap Retained Heap Percentage
java.lang.Thread @ 0×18ff9320 http-8080-1 88 273,945,736 97.01%
java.util.ArrayList @ 0×18ff93a0 24 273,923,048 97.00%
java.lang.Object261945@ 0×23d04040 9,047,792 273,923,024 97.00%
com.starcite.commonsearch.client.vendor.impl.VendorImpl @ 0×16b80000 135 136 0.00%

从这个角度来看,内存是由java.lang.Thread线程@0×18ff9320 http-8080-1。因此,它应该发生在一个HTTP请求中。

然后,在thread details部分中找到这个线程。然后单击线程属性链接。请看:

如何使用Eclipse内存分析器分析内存泄漏

现在您可能会找到一些提示,例如vendorsearchmeditorSearchVendorByIDsInput等。根据这些信息,您可能会找到根代码:

public SearchVendorByIDsOutput searchVendorByIDs(SearchVendorByIDsInput input) {

List<vendor> vendors = new ArrayList</vendor><vendor>();

for (;;) {
VendorImpl v = new VendorImpl();
v.setName("name");
vendors.add(v);
}
}
</vendor>

四. 如何找到占用内存的未使用集合–强大的对象查询语言OQL

在开发过程中,您可能永远不会注意到大量已实例化但从未使用过的集合。

默认容量为10的空ArrayList在32位系统上花费80字节,在64位系统上花费144字节。

如果在我们的应用程序中通常使用MyValueStorage类,并且堆中有它的500.000个实例,那么在32位系统上(64位–144MB)将为specialValues和errors values列表保留80Mb。但只需要5%左右。因此,对这两个字段使用延迟初始化可能是一个好主意(在实际使用之前保持它们为null)。我们要付出的代价是几个“if”语句,以避免遇到NullPointerExceptions

打开对象查询语言Studio以执行语句

如何使用Eclipse内存分析器分析内存泄漏

有关OQL语法的详细说明,请查看帮助页。目前我们只需要几个具体的问题。对于查找enpty和未修改的ArrayListsHashMapsHashtables,它们如下所示:

select * from java.util.ArrayList where size=0 and modCount=0
select * from java.util.HashMap where size=0 and modCount=0
select * from java.util.Hashtable where count=0 and modCount=0

如何使用Eclipse内存分析器分析内存泄漏

然后你可以得到每个项目的保留堆,比如80字节。总共有857个条目。所以,它们不会占用太多的内存。

五. VendorImpl使用了多少内存–强大的对象查询语言

打开对象查询语言Studio以执行语句

运行以下OQL

select * from com.starcite.commonsearch.client.vendor.impl.VendorImpl

如何使用Eclipse内存分析器分析内存泄漏

点击“显示直方图”你会发现VendorImpl的耗费超过260M内存,这很特别。

总之,Eclipse内存分析器是一个非常强大的内存分析器工具。而且更容易发现潜在的内存泄漏。您还可以找到任何java对象所使用的内存。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1326.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册