利用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.iteye.com/topic/233080



10,你遇到的是最理想的情况,但有时候,这种方法不能找到原因,只找到造成崩溃的点.就好比,

一个HTTP 请求,没有设置超时(对不起,默认是不超时,不知道为什么SUN要这样设定),

然后这条线程就卡在这里了,然后,这条线程里的一个堆栈被另一条线程放入内容,

本来这些内容就是要这条闲线程去处理的,但是现在,这条线程卡住了,但是用你说的这种方法,

绝对找不到造成内存泄露的原因是因为http不超时,一直卡在那里.



我还有一个笨办法做精细的内存分配比较:就是定期用pmap命令dump出来JVM进程的内存映射表,然后diff。

http://www.iteye.com/topic/256701



11,http://calvin.iteye.com/blog/91903

java 不是有垃圾收集器了吗?怎么还泄漏啊,唬我啊??

   嗯,此泄漏非比泄漏。C/C++的泄漏,是对象已不可到达,而内存又没有回收,真正的内存黑洞。

   而Java的泄漏,则是因为各种原因,对象对应用已经无用,但一直被持有,一直可到达。

   总结原因无外乎几方面:



   1). 被生命周期极长的集合类不当持有,号称是Java内存泄漏的首因。

      这些集合类的生命周期通常极长,而且是一个辅助管理性质的对象,在一个业务事务运行完后,如果没有将某个业务对象主动的从中清除的话,这个集合就会吃越来越多内存,可以用WeakReference,如WeakHashMap,使得它持有的对象不增加对象的引用数。

   2). Scope定义不对,这个很简单了,方法的局部变量定义成类的变量,类的静态变量等。

   3). 异常时没有加finally{}来释放某些资源,JDBC时代也是很普遍的事情。

   4). 另外一些我了解不深的原因,如:Swing里的Listener没有显式remove;内部类持有外部对象的隐式引用;Finalizers造成关联对象没有被及时清空等。