如果有些系统的性能不是很稳定,随着时间的变化而变化,那么就要怀疑系统是否存在内存泄漏了。特别是哪些随时间的推移越来越慢的系统,很大程度上是Java内存对象有了泄漏。
不是说Java虚拟机是自动回收内存吗?怎么还存在内存泄漏?
事实上,有些内存泄漏是无法通过其它手段避免的,只能由编程开发人员在编程的时候主动避免。Java虚拟机的确可以将没有用的对象自动回收掉,可是有些泄漏是程序员的疏漏,一直保持了本应该释放的对象,因此Java虚拟机不认为这些对象是没有用的,因为他们跟其它有用的对象没什么区别,还有引用指着这些对象。这种情况就只能从源码着手了,找出内存泄漏的根源。Java虚拟机提供了很多工具来定位内存泄漏的位置。在Sun的Hotspot中,主要有jmap和jhat。
jmap
jmap命令用于查看当前java进程或者core dump文件,显示当前存在与内存中的对象分布情况,包括对象所属的类,对象的个数和所占内存的大小,并且依所占用的内存大小的顺序排列。用下面命令查找java的pid:
ps -ef|grep java
然后查看java进程的内存对象分布:
jmap -histo pid
结果如图:
C:\Documents and Settings\Administrator>jmap -histo 180
num #instances #bytes class name
----------------------------------------------
1: 13352 60321384 [B
2: 108823 13516768 <constMethodKlass>
3: 89912 9476704 [C
4: 108823 8710200 <methodKlass>
5: 152780 6715552 <symbolKlass>
6: 8796 5325984 <constantPoolKlass>
7: 8796 4219536 <instanceKlassKlass>
8: 16753 3896104 [I
9: 7026 2782816 <constantPoolCacheKlass>
10: 109717 2633208 java.lang.String
11: 40391 969384 java.util.HashMap$Entry
12: 13806 932104 [Ljava.lang.Object;
13: 9400 902400 java.lang.Class
14: 8076 854312 [Ljava.util.HashMap$Entry;
15: 11426 794936 [S
16: 13935 685408 [[I
但是有时候光知道对象的数量和内存占用量是不够的,因为这些数据只是提供了有可能泄漏的对象,没有告诉这些对象是什么地方分配的。要定位内存泄漏还需要更多的信息。这时候就需要jhat工具了。
jhat在使用jhat之前,还需要用jmap获得更加详细的数据。一般用下面命令获得一个二进制的输出文件:
C:\Documents and Settings\Administrator>jmap -dump:file=heap.bin 180
Dumping heap to C:\Documents and Settings\Administrator\heap.bin ...
Heap dump file created
然后用下面的命令用jhat来分析这个文件:
C:\Documents and Settings\Administrator>jhat -J-mx512m heap.bin
Reading from heap.bin...
Dump file created Mon Dec 06 23:36:22 CST 2010
Snapshot read, resolving...
Resolving 713062 objects...
.................
Eliminating duplicate references................................................
......................................................................Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
这个命令会启动一个Web服务器,并在7000端口上监听。这时候可以借助浏览器访问http://localhost:7000,这个页面可以看到很多详细的信息,包括哪些对象是哪些类创建的。可以从http://localhost:7000/histo/入手,这个页面不但可以看到当前内存中对象的情况,还可以点击每一种对象来查找哪些正在使用此对象的其它对象,如下图:
另外http://localhost:7000/showInstanceCounts/includePlatform/页面可以想jmap命令一样,提供对象实例的数量和大小的信息,如下图:
此外值得一提的是查询页面http://localhost:7000/oql/,这个页面可以让你输入类似数据库sql查询语句,根据需求定位到相关的信息,如下图:
- 大小: 118.1 KB
- 大小: 162.1 KB
- 大小: 24.4 KB
分享到:
相关推荐
ie客户端测试内存泄露工具,内置ie浏览器
内有详细安装步骤,以vc6为例,只需加入一个头文件,在debug运行完成后,会在调试信息内显示泄露的内存,并能点击定位到代码行,非常好用。
OOMDetector是一个iOS内存监控组件,应用此组件可以帮助你轻松实现OOM监控、大内存分配监控、内存泄漏检测等功能。 特性 1.OOM监控:监控OOM,Dump引起爆内存的堆栈 2.大内存分配监控:监控单次大块内存分配,提供...
AQTime进行内存泄露和资源泄漏监控.pdf
可以查看DOM元素的各种属性,可以监控浏览器内存泄漏
这是一款绿色软件,无需安装,内部嵌入了一个IE 浏览器控件,用户可以通过该控件访问需要测试的网页。
OOMDetector是一个iOS内存监控组件,应用此组件可以帮助你轻松实现OOM监控、大内存分配监控、内存泄漏检测等功能。 特性 1.OOM监控:监控OOM,Dump引起爆内存的堆栈 2.大内存分配监控:监控单次大块内存分配...
NULL 博文链接:https://kennylee26.iteye.com/blog/1402260
java内存泄露查询的几个命令系统命令的使用说明
JProfiler是一款Java的性能监控工具。可以查看当前应用的对象、对象引用、内存、CPU使用情况、线程、线程运行情况(阻塞、等待等),同时可以查找应用内存使用得热点。
Android平台下井下安全监控系统存在内存泄露问题。经过分析认为Java内存泄露是破坏系统的主要因素。文章着重介绍了在Android平台下开发应用程序中,内存泄露出现的原因及相应的解决办法,并通过示例程序进行说明。
iOS的内存监控组件,为您提供OOM监控,内存分配监控,内存泄漏检测等功能。
中Java应用内存泄漏的检测,通过监控集合类对象的内存消耗和集合内元素的 使用情况,得出对象内存泄漏的可能性大小,量化对象内存泄漏的风险。检测 系统首先收集垃圾回收事件后的应用内存数据,确定进行...
是一款运行时C/C++内存泄漏分析工具,其检测结果专业、准确,操作却极其简单,可以帮助C/C++程序员迅速解决内存泄漏。TMM中引入GC机制,内存泄露检测准确率可达100%,无需内存快照,不影响目标程序性能,极简操作,...
监控用户指定任意进行的内存使用情况,并输出log日志,作为后期检查是否有内存泄露而用,非常有用,还在迷茫的小伙帮们快来
当分配了一块内存,并设置了对象之后,如果在使用完了之后忘记释放,这就会发生内存泄露。这意味着系统是无法回收内存并交予他人使用,这也最终意味着我们的内存将会逐渐耗尽。在Facebook,有很多工程师在代码库的...
关于C++程序的内存泄露和监控的代码和文档
重点关注如何去监控和发现内存问题;此外分析出问题还要如何解决内存问题。下面就开始本篇的内容:第一部分概念众所周知,java中的内存java虚拟机自己去管理的,他不想C++需要自己去释放。笼统地去讲,java的内存...
用于检测Moss2007API内存泄漏的工具
这个是我自己写的工具, 希望加上内存监控以后, 程序不会被拖得很慢,让用户感觉到。 这样就可以在用户的生产环境加上内存泄露检查工具。 这个工具还不成熟请绕开