利用jdk6查内存泄漏(见
编写对GC友好,又不泄漏的代码)
(1)jmap -dump:file=heap_file_name pid 会产生一个heap_file_name文件
(2)jhat heap_file_name,然后打开浏览器
http://localhost:7000/ 浏览。
可看到里面显示了运行的所有的类和实例及大小。平台(例如tomcat)的不会包括在里面。
(3)如果觉得不够,还可以把heap_file_name文件加一个bin的后缀,然后让Eclipse MAT来分析。看
这里。
另外
jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。
jinfo:的用处比较简单,就是能输出并修改运行时的java进程的运行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
jstat 也很有用,说明见
这里3,
SUN JDK所支持的典型选项以及说明:http: //java.sun.com/javase/technologies/hotspot/vmoptions.jsp 上面有很多选项
-XX:-HeapDumpOnOutOfMemoryError 从jdk1.4.2 update 12 和java 5 update 7开始支持这个选项。
4,
关于jmap
从JDK 5开始,SUN JDK开始提供JMap的工具。但是仅仅是实验性质的,而且只有在solaris平台上有。
后来Jmap被反向移植到jdk 1.4.2_09。因为是实验性质,所以jmap可能会出现dump失败的情况。
但是自从JDK 6之后,jmap的稳定性和可用性都没问题了。请注意各个版本的jvm都要用自己版本的jmap,
而jhat可以用于分析各个版本的jmap dump出来的文件。至于jhat用于分析1g以上的dump文件,
我们有过多次在笔记本上的成功经历,它对内存的要求可能并没有那么高。
http://space.itpub.net/27378/viewspace-521225
5,J2SE6中使用jhat来分析内存堆
http://hi.baidu.com/tister/blog/item/e7374482f4341ca70cf4d2e8.html
6,Java内存溢出(OutOfMemory),内存分析相关工具
http://uglytroll.ycool.com/post.3046111.html
7,JDK中的好工具 jmap、jhat
http://wangzaixiang.blogspot.com/2008/10/jdk-jmapjhat.html
http://hi.baidu.com/zeorliu/blog/item/4f38989413601719d21b70d5.html
8,SAP贡献给eclipse基金会的MemoryAnalyzer,原来叫Java Memory Analysis
能分析几G的Memory Dump而不会内存溢出?
http://www.eclipse.org/mat/
可惜还是只支持jdk1.4.2 update 12 和java 5 update 7以上
9,在一个方法里面的变量是不会引起内存泄露的。
内存泄露都是发生在类变量和实例变量(且此实例被缓存、如单例模式)里。
我建议你从HashMap、HashMap$Entry 入手查查。
我也研究过一阵子的内存泄露问题,最终解决了。
http://www.javaeye.com/topic/233080
10,你遇到的是最理想的情况,但有时候,这种方法不能找到原因,只找到造成崩溃的点.就好比,
一个HTTP 请求,没有设置超时(对不起,默认是不超时,不知道为什么SUN要这样设定),
然后这条线程就卡在这里了,然后,这条线程里的一个堆栈被另一条线程放入内容,
本来这些内容就是要这条闲线程去处理的,但是现在,这条线程卡住了,但是用你说的这种方法,
绝对找不到造成内存泄露的原因是因为http不超时,一直卡在那里.
我还有一个笨办法做精细的内存分配比较:就是定期用pmap命令dump出来JVM进程的内存映射表,然后diff。
http://www.javaeye.com/topic/256701
11,http://calvin.javaeye.com/blog/91903
java 不是有垃圾收集器了吗?怎么还泄漏啊,唬我啊??
嗯,此泄漏非比泄漏。C/C++的泄漏,是对象已不可到达,而内存又没有回收,真正的内存黑洞。
而Java的泄漏,则是因为各种原因,对象对应用已经无用,但一直被持有,一直可到达。
总结原因无外乎几方面:
1). 被生命周期极长的集合类不当持有,号称是Java内存泄漏的首因。
这些集合类的生命周期通常极长,而且是一个辅助管理性质的对象,在一个业务事务运行完后,如果没有将某个业务对象主动的从中清除的话,这个集合就会吃越来越多内存,可以用WeakReference,如WeakHashMap,使得它持有的对象不增加对象的引用数。
2). Scope定义不对,这个很简单了,方法的局部变量定义成类的变量,类的静态变量等。
3). 异常时没有加finally{}来释放某些资源,JDBC时代也是很普遍的事情。
4). 另外一些我了解不深的原因,如:Swing里的Listener没有显式remove;内部类持有外部对象的隐式引用;Finalizers造成关联对象没有被及时清空等。
搭车
我的SQL调优公式T=S/V
http://space.itpub.net/27378/viewspace-157789
MetaWidget及SOA
http://wangzaixiang.blogspot.com/2008/10/metawidget.html