利用jdk6查內(nèi)存泄漏(見
編寫對GC友好,又不泄漏的代碼)
(1)jmap -dump:file=heap_file_name pid 會產(chǎn)生一個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進程的運行參數(shù)。用法是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,
關(guān)于jmap
從JDK 5開始,SUN JDK開始提供JMap的工具。但是僅僅是實驗性質(zhì)的,而且只有在solaris平臺上有。
后來Jmap被反向移植到j(luò)dk 1.4.2_09。因為是實驗性質(zhì),所以jmap可能會出現(xiàn)dump失敗的情況。
但是自從JDK 6之后,jmap的穩(wěn)定性和可用性都沒問題了。請注意各個版本的jvm都要用自己版本的jmap,
而jhat可以用于分析各個版本的jmap dump出來的文件。至于jhat用于分析1g以上的dump文件,
我們有過多次在筆記本上的成功經(jīng)歷,它對內(nèi)存的要求可能并沒有那么高。
http://space.itpub.net/27378/viewspace-521225
5,J2SE6中使用jhat來分析內(nèi)存堆
http://hi.baidu.com/tister/blog/item/e7374482f4341ca70cf4d2e8.html
6,Java內(nèi)存溢出(OutOfMemory),內(nèi)存分析相關(guān)工具
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而不會內(nèi)存溢出?
http://www.eclipse.org/mat/
可惜還是只支持jdk1.4.2 update 12 和java 5 update 7以上
9,在一個方法里面的變量是不會引起內(nèi)存泄露的。
內(nèi)存泄露都是發(fā)生在類變量和實例變量(且此實例被緩存、如單例模式)里。
我建議你從HashMap、HashMap$Entry 入手查查。
我也研究過一陣子的內(nèi)存泄露問題,最終解決了。
http://www.javaeye.com/topic/233080
10,你遇到的是最理想的情況,但有時候,這種方法不能找到原因,只找到造成崩潰的點.就好比,
一個HTTP 請求,沒有設(shè)置超時(對不起,默認(rèn)是不超時,不知道為什么SUN要這樣設(shè)定),
然后這條線程就卡在這里了,然后,這條線程里的一個堆棧被另一條線程放入內(nèi)容,
本來這些內(nèi)容就是要這條閑線程去處理的,但是現(xiàn)在,這條線程卡住了,但是用你說的這種方法,
絕對找不到造成內(nèi)存泄露的原因是因為http不超時,一直卡在那里.
我還有一個笨辦法做精細(xì)的內(nèi)存分配比較:就是定期用pmap命令dump出來JVM進程的內(nèi)存映射表,然后diff。
http://www.javaeye.com/topic/256701
11,http://calvin.javaeye.com/blog/91903
?java 不是有垃圾收集器了嗎?怎么還泄漏啊,唬我啊??
?? 嗯,此泄漏非比泄漏。C/C++的泄漏,是對象已不可到達(dá),而內(nèi)存又沒有回收,真正的內(nèi)存黑洞。
?? 而Java的泄漏,則是因為各種原因,對象對應(yīng)用已經(jīng)無用,但一直被持有,一直可到達(dá)。
?? 總結(jié)原因無外乎幾方面:
?? 1). 被生命周期極長的集合類不當(dāng)持有,號稱是Java內(nèi)存泄漏的首因。
????? 這些集合類的生命周期通常極長,而且是一個輔助管理性質(zhì)的對象,在一個業(yè)務(wù)事務(wù)運行完后,如果沒有將某個業(yè)務(wù)對象主動的從中清除的話,這個集合就會吃越來越多內(nèi)存,可以用WeakReference,如WeakHashMap,使得它持有的對象不增加對象的引用數(shù)。
?? 2). Scope定義不對,這個很簡單了,方法的局部變量定義成類的變量,類的靜態(tài)變量等。
?? 3). 異常時沒有加finally{}來釋放某些資源,JDBC時代也是很普遍的事情。
?? 4). 另外一些我了解不深的原因,如:Swing里的Listener沒有顯式remove;內(nèi)部類持有外部對象的隱式引用;Finalizers造成關(guān)聯(lián)對象沒有被及時清空等。
?
搭車
我的SQL調(diào)優(yōu)公式T=S/V
http://space.itpub.net/27378/viewspace-157789
MetaWidget及SOA
http://wangzaixiang.blogspot.com/2008/10/metawidget.html