java jmap 分析_利用java虚拟机的工具jmap分析java内存情况
有時候碰到性能問題,比如一個java application出現(xiàn)out of memory,出現(xiàn)內(nèi)存泄漏的情況,再去修改bug可能會變得異常復雜,利用工具去分析整個java application 內(nèi)存占用情況,然后再去走查代碼。
首先先看一下,java內(nèi)存分配的基本模型,由于JVM內(nèi)存劃分比較復雜,這里只是簡單的說一下java內(nèi)存劃分
java 堆(heap):
Java?堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。此內(nèi)存區(qū)域的
唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存。
Java?堆是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱做“GC?堆”
所以Java?堆中還可以細分為:新生代和老年代;
新生代:所有新生成的對象首先都是放在年輕代的。年輕代的目標就是盡可能快速的收集掉那些生命周期短的對象。
老年代(old Generation):在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對象,就會被放到年老代中。因此,可以認為年老代中存放的都是一些生命周期較長的對象
持久代(Prem Generation):用于存放靜態(tài)文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate等,在這種時候需要設(shè)置一個比較大的持久代空間來存放這些運行過程中新增的類。持久代大小通過-XX:MaxPermSize=進行設(shè)置。
再細致一點的有Eden?空間、From Survivor?空間、To Survivor?空間等。如果從內(nèi)存分配
的角度看,線程共享的Java?堆中可能劃分出多個線程私有的分配緩沖區(qū)(Thread Local
Allocation Buffer,TLAB)。不過,無論如何劃分,都與存放內(nèi)容無關(guān),無論哪個區(qū)域,
存儲的都仍然是對象實例,進一步劃分的目的是為了更好地回收內(nèi)存,或者更快地分配內(nèi)存。
java 棧區(qū):
JVM中運行的每個線程都擁有自己的線程棧,線程棧包含了當前線程執(zhí)行的方法調(diào)用相關(guān)信息,我們也把它稱作調(diào)用棧。隨著代碼的不斷執(zhí)行,調(diào)用棧會不斷變化。
一般認為 方法,局部變量,對象的引用 都是存在棧區(qū)內(nèi)的。
java方法區(qū):
方法區(qū)(Method Area)與Java?堆一樣,是各個線程共享的內(nèi)存區(qū)域,它用于存
儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。
很多人稱之為永生代(Permanent Generation);
出現(xiàn)out of memory 接著會出現(xiàn) java heap space,這種情況是堆空間滿了,
可能出現(xiàn)的情況,比如一個方法 進棧了,里面有一段邏輯,最常見的就是打個比方
public void method(){
List list=...;
.... 執(zhí)行代碼的邏輯
}
這個list 里面有N多對象,但是執(zhí)行下面的邏輯時內(nèi)存溢出,這是因為方法在沒有出棧之前,java heap中的對象太多(方法在出棧之后GC 對 沒有引用的 對象進行垃圾回收)。
還有 就是有一些全局的變量或者集合 ,或者存在方法區(qū)的 內(nèi)存 沒有進行及時清理,導致內(nèi)存沒有釋放,這種稱之為真泄漏。
2.1 利用jmap 進行內(nèi)存分析,
jmap -heap pid //打印heap空間的概要,這里可以粗略的檢驗heap空間的使用情況。
Heap Configuration:指java應(yīng)用啟動時設(shè)置的JVM參數(shù)。像最大使用內(nèi)存大小,年老代,年青代,持久代大小等。
Heap Usage:當時的heap實際使用情況。包括新生代、老生代和持久代。
其中新生代包括:Eden區(qū)的大小、已使用大小、空閑大小及使用率。Survive區(qū)的From和To同樣。
有這個可以很簡單的查看本進程的內(nèi)存使用情況。
可以用于分析堆內(nèi)存分區(qū)大小是否合理,新生代和老生代的大小分配是否合適等。
也許進程占用的總內(nèi)存比較多,但我們在這里可以看到真正用到的并沒有多少,很多都是"Free"。內(nèi)存使用的堆積大多在老年代,內(nèi)存池露始于此,所以要格外關(guān)心“Old Generation”。
jmap -histo PID //這里會生成一個類的統(tǒng)計報表,此表非常簡單,如顯示什么類有多少個實例,共占了多少字節(jié)等。
2.2 ?利用jmap 生成dump 文件,然后再利用mat工具進行分析。
jmap -dump:live,format=b,file=‘文件名 ’2657 //2657 是進程的PID 號
生成轉(zhuǎn)儲文件之后,file -open(該轉(zhuǎn)儲文件)
上面的餅狀圖顯示了內(nèi)存分配的比例,通過dominator_tree可以看到詳細信息。
總結(jié)
以上是生活随笔為你收集整理的java jmap 分析_利用java虚拟机的工具jmap分析java内存情况的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新能源产业迎重大利好!碳酸锂价格三个月大
- 下一篇: 台积电称美国工厂明年量产4nm!高通承诺