個人對JVM五大部分的總結(歡迎網友指點、補充、指出錯誤)

因爲我對Heap的文字描述比較多,先單獨抽取出來:

--------

--------

new對象、數組等分配的內存空間。

heap又分爲新生代Young和老年代Old(兩者1:2大小)。新生代細拆爲3部分(Eden、from、to,8:1:1),from和to合稱爲Survivor區。

新分配的對象先到新生代的Eden區,要是Eden放不下,就會觸發Minor GC垃圾回收,新生代使用的GC算法爲引用計數法,首先Eden中存活的對象(仍然有在程序運行中被引用,這個引用可能是Method方法區中的常量池存儲的引用【String引用、或者非浮點數的引用池-128~127】,也可能不是)放到to區,要是to有放不下的部分(比如一個很大的對象,例如一個大數組之類的),就直接放到old老年代區域;接着from區,要是裏面的對象引用計數達標(一般是15,或者你可以另外自己設置),就直接把這個對象放到Old老年代,其他存活對象放到to區,同樣放不下的也是直接放old區,然後沒有存活的(也就是引用計數爲0,其他人不引用這個對象了)就捨棄;to區沒有所謂的變動,這裏提一下,“GC算法指的是把符合XXX條件的東西視爲還活着的對象的算法”,前面提到的Minor GC指的是新生代進行一次垃圾回收的整個過程,新生代垃圾回收的方式是複製算法,就是上述的把存活的複製到to或者old區域,然後沒存活的就回收其內存空間,這樣內存內有碎片,即內存不是連續的,但是新生代垃圾回收比較頻繁,使用這種複製算法來垃圾回收效率高,而且本省新生代佔用heap的空間也就1/3,所以浪費的內存空間可以接收。

接着談Old區,Old區就是老年代,裏面的對象要麼是Young中存活下來的經常被引用的小對象,要麼就是引用次數不一定多、但是佔用內存很大所以被直接分配過來的大對象。這裏有個帶有歧義的問題,我也無法下定論,就是Major GC和Full GC區別,有人說前者是老年代的GC,有人說前者是永久代的GC,Full GC則有說是老年代回收、也有說是新老年代回收,更有說是所有內存的回收。這裏不多糾結,但是隻要知道Major GC和Full GC往往都會涉及到老年代的GC。觸發老年代GC的條件有很多,這裏只簡單列舉,比如新生代的對象進入老年代過於頻繁,其速度大於了老年代回收的速度,平均下來老年代將不夠新生代的對象進入;或者簡單粗暴老年代空間不夠用了,那麼肯定得進行Old區的GC流程。其他觸發Old區回收的情況自行查詢、腦補,基本都是圍繞着老年代空間將要或者已經不夠用展開的話題。Old區的GC算法是可達性算法{{可達性算法通過遍歷GC ROOT根節點來判斷對象是否被引用,避免了引用計數法出現的2個垃圾對象互相引用而不被回收的尷尬場景,可以理解爲java程序裏面把所有的引用用一張無向圖表示,每個引用之間有一條邊,這樣就形成複雜的圖,而互相引用的垃圾對象自成一個環路,和GC ROOT節點所在的大無相圖沒有聯繫,這樣就可以把這中垃圾引用對象視爲無用對象,被回收。什麼對象能作爲GC ROOT,一般指的是垃圾回收器對象【其有一套規則指定哪些對象可以作爲GC ROOT,java中的GC ROOT對象通常包括:JVM Stack中棧幀Stack Frame的本地變量表引用的對象、Method Area的類靜態屬性引用的對象(jdk1.8應該歸到堆中,1.8之前爲永久代中)、方法區常量引用的對象(1.8改把常量池放堆中,而1.8之前方法區以永久代實現,所以放在永久代,物理內存上和堆相近,概念上包含在方法區中,重申1.8的方法區實現爲元空間,然後去除永久代,原本永久代的東西只剩類的元信息放在元空間,物理上內存獨立於JVM、在本地機器的內存上,而那些常量池、靜態變量等轉移到堆中)、本地方法棧JNI的引用對象(本地方法棧就是每個線程都各自有一個,調用Native方法的,即非Java方法,而另一個類似的JVM棧則調用java方法,兩者都是把方法執行過程中用到的局部變量表、操作數棧、動態鏈接、方法出口等放到棧幀,然後棧幀入棧、出棧表示方法執行、方法執行完)】}},可達性算法相對複雜一點,但是因爲Old區的垃圾回收比較不頻繁,所以損失也比較少,同樣也因爲是垃圾回收比較少,更需要精準的回收之前被忽略的垃圾對象(比如互相引用導致引用計數不爲0,但是沒有在程序中起到作用的對象)。Old區標記完可達性算法總結出來的可達對象後,把不可達的垃圾對象回收,然後把剩餘的可達對象的內存進行整理,整理成連續的空間(並且刪除所有剛纔臨時計算是否可達,用到的標記),這叫作標記-整理(垃圾回收算法),和前面的新生代用到的垃圾回收算法(複製算法)不一樣,突出點就是多了內存的碎片整理,但是這樣效率會低一點。不過Old區域垃圾回收相較不頻繁,所以空間也比較寶貴,值得效率低一點但是空間利用率更高的垃圾回收算法(標記-整理)。

ps:Old垃圾回收提到了GC ROOT對象的判定往往取決於 垃圾回收器指定的規則,垃圾回收器有很多,具體的區別不多做展開介紹,只簡單列取幾個名稱:Serial收集器、Serial Old收集器、ParNew收集器、Parallel Scavenge收集器、 Parallel Old收集器、CMS(Concurrent Mark Sweep)收集器。

--------

--------

下面貼我自己的總結圖(點擊後放大是沒有變形的,建議下載下來或者拖動到新的窗口頁面打開。剛補充了一點點,重新貼了圖)

發佈了60 篇原創文章 · 獲贊 8 · 訪問量 5776
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章