Jconsole,jProfile,VisualVMjava
Jconsole:jdk自帶,功能簡單,可是能夠在系統有必定負荷的狀況下使用。對垃圾回收算法有很詳細的跟蹤。算法
JProfiler:商業軟件,須要付費。功能強大。工具
VisualVM:JDK自帶,功能強大,與JProfiler相似。推薦。優化
觀察內存釋放狀況、集合類檢查、對象樹spa
上面這些調優工具都提供了強大的功能,可是總的來講通常分爲如下幾類功能操作系統
堆信息查看線程
可查看堆空間大小分配(年輕代、年老代、持久代分配)設計
提供即時的垃圾回收功能對象
垃圾監控(長時間監控回收狀況)遞歸
查看堆內類、對象信息查看:數量、類型等
對象引用狀況查看
有了堆信息查看方面的功能,咱們通常能夠順利解決如下問題:
--年老代年輕代大小劃分是否合理
--內存泄漏
--垃圾回收算法設置是否合理
線程信息監控:系統線程數量。
線程狀態監控:各個線程都處在什麼樣的狀態下
Dump線程詳細信息:查看線程內部運行狀況
死鎖檢查
熱點分析
CPU熱點 :檢查系統哪些方法佔用的大量CPU時間
內存熱點 :檢查哪些對象在系統中數量最大(必定時間內存活對象和銷燬對象一塊兒統計)
這兩個東西對於系統優化頗有幫助。咱們能夠根據找到的熱點,有針對性的進行系統的瓶頸查找和進行系統優化,而不是漫無目的的進行全部代碼的優化。
快照
快照是系統運行到某一時刻的一個定格。在咱們進行調優的時候,不可能用眼睛去跟蹤全部系統變化,依賴快照功能,咱們就能夠進行系統兩個不一樣運行時刻,對象(或類、線程等)的不一樣,以便快速找到問題
舉例說,我要檢查系統進行垃圾回收之後,是否還有該收回的對象被遺漏下來的了。那麼,我能夠在進行垃圾回收先後,分別進行一次堆狀況的快照,而後對比兩次快照的對象狀況。
內存泄漏是比較常見的問題,並且解決方法也比較通用,這裏能夠重點說一下,而線程、熱點方面的問題則是具體問題具體分析了。
內存泄漏通常能夠理解爲系統資源(各方面的資源,堆、棧、線程等)在錯誤使用的狀況下,致使使用完畢的資源沒法回收(或沒有回收),從而致使新的資源分配請求沒法完成,引發系統錯誤。
內存泄漏對系統危害比較大,由於他能夠直接致使系統的崩潰。
要區別一下,內存泄漏和系統超負荷二者是有區別的,雖然可能致使的最終結果是同樣的。內存泄漏是用完的資源沒有回收引發錯誤,而系統超負荷則是系統確實沒有那麼多資源能夠分配了(其餘的資源都在使用)。
年老代堆空間被佔滿
異常: java.lang.OutOfMemoryError: Java heap space
說明:
這是最典型的內存泄漏方式,簡單說就是全部堆空間都被沒法回收的垃圾對象佔滿,虛擬機沒法再在分配新空間。
如上圖所示,這是很是典型的內存泄漏的垃圾回收狀況圖。全部峯值部分都是一次垃圾回收點,全部谷底部分表示是一次垃圾回收後剩餘的內存。鏈接全部谷底的 點,能夠發現一條由底到高的線,這說明,隨時間的推移,系統的堆空間被不斷佔滿,最終會佔滿整個堆空間。所以能夠初步認爲系統內部可能有內存泄漏。(上面 的圖僅供示例,在實際狀況下收集數據的時間須要更長,好比幾個小時或者幾天)
解決:
這種方式解決起來也比較容易,通常就是根據垃圾回收先後狀況對比,同時根據對象引用狀況(常見的集合對象引用)分析,基本均可以找到泄漏點。
持久代被佔滿
異常: java.lang.OutOfMemoryError: PermGen space
說明:
Perm空間被佔滿。沒法爲新的class分配存儲空間而引起的異常。這個異常之前是沒有的,可是在Java反射大量使用的今天這個異常比較常見了。主要緣由就是大量動態反射生成的類不斷被加載,最終致使Perm區被佔滿。
更可怕的是,不一樣的classLoader即使使用了相同的類,可是都會對其進行加載,至關於同一個東西,若是有N個classLoader那麼他將會被加載N次。所以,某些狀況下,這個問題基本視爲無解。固然,存在大量classLoader和大量反射類的狀況其實也很少。
解決:
1. -XX:MaxPermSize=16m
2. 換用JDK。好比JRocket。
堆棧溢出
異常: java.lang.StackOverflowError
說明: 這個就很少說了,通常就是遞歸沒返回,或者循環調用形成
線程堆棧滿
異常:Fatal: Stack size too small
說明:java中一個線程的空間大小是有限制的。JDK5.0之後這個值是1M。與這個線程相關的數據將會保存在其中。可是當線程空間滿了之後,將會出現上面異常。
解決:增長線程棧大小。-Xss2m。但這個配置沒法解決根本問題,還要看代碼部分是否有形成泄漏的部分。
系統內存被佔滿
異常 :java.lang.OutOfMemoryError: unable to create new native thread
說明 :
這個異常是因爲操做系統沒有足夠的資源來產生這個線程形成的。系統建立線程時,除了要在Java堆中分配內存外,操做系統自己也須要分配資源來建立線程。所以,當線程數量大到必定程度之後,堆中或許還有空間,可是操做系統分配不出資源來了,就出現這個異常了。
分配給Java虛擬機的內存愈多,系統剩餘的資源就越少,所以,當系統內存固定時,分配給Java虛擬機的內存越多,那麼,系統總共可以產生的線程也就越少,二者成反比的關係。同時,能夠經過修改-Xss來減小分配給單個線程的空間,也能夠增長系統總共內生產的線程數。
解決:
1.從新設計系統減小線程數量。
2.線程數量不能減小的狀況下,經過-Xss減少單個線程大小。以便能生產更多的線程。