java内存泄漏笔记

发布时间:2014-10-25 2:21:14
来源:分享查询网

利用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-5212255,J2SE6中使用jhat来分析内存堆http://hi.baidu.com/tister/blog/item/e7374482f4341ca70cf4d2e8.html6,Java内存溢出(OutOfMemory),内存分析相关工具http://uglytroll.ycool.com/post.3046111.html7,JDK中的好工具 jmap、jhathttp://wangzaixiang.blogspot.com/2008/10/jdk-jmapjhat.htmlhttp://hi.baidu.com/zeorliu/blog/item/4f38989413601719d21b70d5.html8,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/23308010,你遇到的是最理想的情况,但有时候,这种方法不能找到原因,只找到造成崩溃的点.就好比,一个HTTP 请求,没有设置超时(对不起,默认是不超时,不知道为什么SUN要这样设定),然后这条线程就卡在这里了,然后,这条线程里的一个堆栈被另一条线程放入内容,本来这些内容就是要这条闲线程去处理的,但是现在,这条线程卡住了,但是用你说的这种方法,绝对找不到造成内存泄露的原因是因为http不超时,一直卡在那里.我还有一个笨办法做精细的内存分配比较:就是定期用pmap命令dump出来JVM进程的内存映射表,然后diff。 http://www.javaeye.com/topic/25670111,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/Vhttp://space.itpub.net/27378/viewspace-157789MetaWidget及SOAhttp://wangzaixiang.blogspot.com/2008/10/metawidget.html 来源:http://www.blogjava.net/leekiang/archive/2009/01/14/251270.html

返回顶部
查看电脑版