首頁  >  文章  >  Java  >  java中JVM記憶體如何分配與管理?

java中JVM記憶體如何分配與管理?

青灯夜游
青灯夜游轉載
2018-10-22 17:37:443814瀏覽

本篇文章帶給大家的內容是介紹java中JVM記憶體如何分配與管理?讓大家了解JVM的垃圾回收演算法和JVM的記憶體分配機制。有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

一.垃圾蒐集演算法

  • JVM中的記憶體分配機制

    垃圾回收演算法有標記-清除演算法,標記-整理演算法和複製演算法,JVM使用分代收集演算法來回收JVM分配的記憶體空間,分代收集演算法分為新生代和老年代,主要收集JVM記憶體模型中的堆內存,其中新生代使用複製演算法,老年代使用標記-整理演算法,以下探討下垃圾回收演算法的具體想法。

  • 標記-清除演算法:
    標記清除演算法分為標記和清除兩個階段,首先標記出需要回收的記憶體空間,在標記完成後統一回收所有被標記的對象。它的主要確定有兩個:1.它的標記和清除的效率都不高。 2.它清除物件空間後會產生大量不連續的記憶體碎片,使得再分配大物件(需要使用大量連續記憶體的物件)時因記憶體不足問題而提前觸發垃圾回收。它的回收過程如下圖所示。

java中JVM記憶體如何分配與管理?

  • 複製演算法
    複製演算法將記憶體容量分割成相等的兩塊,每次使用其中的一塊內存,當這塊內存使用完了,就將這塊內存中存活的對象複製到另一塊內存中,然後清空這塊內存空間,下次的對象分配到另一塊內存空間中,也就是存儲的有對象的那塊,兩塊記憶體空間交替使用。在JVM堆記憶體中的新生代分為Eden空間,from survivor空間和to survivor空間。預設Eden和survivor空間比例是8:1,其中Eden佔80%,from 和 to 各佔10%,所有新生代的記憶體能夠利用的空間為90%。在新生代中,每次垃圾回收都會有大量的物件被回收掉,所以只需要複製存活的少數物件即可。以下是複製演算法的操作過程:

java中JVM記憶體如何分配與管理?

  • #標記-整理演算法:
    複製演算法在物件存活率較高的情況下並不好用,因為它要經過複製大量的存活對象。更關鍵的是,複製演算法會有一些空間浪費掉。因為老年代保存的是一些存活週期比較長的對象,所以不適合用複製演算法。根據老年代的特點,產生了標記-整理演算法。標記-整理演算法先標記存活的對象,然後讓他們向一端移動,之後再釋放掉端邊界以外的物件記憶體。標記-整理演算法執行過程如下:

java中JVM記憶體如何分配與管理?

#二.記憶體分配與回收策略
java技術體系中所提倡的自動記憶體管理最終可以歸結為自動化的給物件分配記憶體以及回收分配給物件的記憶體。關於回收內存可以參考上面的垃圾收集算法,JVM採用分代垃圾回收算法來回收對象內存,分為新生代和老年代,新生代使用複製算法,老年代使用標記-整理算法。以下來看下JVM的記憶體分配策略:

  • 物件優先在Eden區分配
    大多數情況下,物件在新生代Eden區分配。當Eden區沒有足夠的記憶體空間進行分配時,虛擬機將發起一次Minor GC(新生代GC)來回收新生代中已經死亡的對象,存活的對象存儲到survivor區中,如果survivor區沒有足夠的空間存儲,將透過空間分配擔保直接存入老年代。之後把物件存入Eden區。

  • 大物件直接進入老年代
    大物件指的是需要大量連續記憶體空間的對象,最典型的大物件為很長的字串和很長的陣列。大物件對虛擬機器的記憶體分配來說是一個壞消息,經常出現大物件容易導致記憶體還有不少空間時就提前觸發垃圾回收及產生連續的空間來存放大物件。不大對象更糟糕的情況是遇到一群「短命」的大對象,寫程式時應避免。

  • 長期存活的物件進入老年代
    既然虛擬機採用了分代收集的思想來管理內存,那麼虛擬機就要知道哪些物件應該放在新生代,哪些物件應該放在老年代。虛擬機器給每個物件了一個年齡計數器。如果這個對像在Eden區中經歷了一此Minor GC,並存儲到了survivor區中,那這個對象的年齡為1,每熬過一次MinorGC,對象的年齡加1,當他的年齡增加到一定程度(預設是15歲),就會晉升到老年代中。

  • 動態物件年齡判定
    為了能更好的適應不同程式的記憶體狀況,虛擬機器並不總是只有在物件的年齡達到一定程度時才讓物件進入老年代,如果在survivor空間的相同年齡的物件記憶體總和大於survivor空間記憶體的一半時,大於等於這個年齡的物件將進入老年代。

  • 空間分配擔保
    老年代會為新生代的內存分配做擔保,也就是說在進行Minor GC之前,虛擬機會先檢查老年代的最大連續可用內存空間是否大於等於新生代所有物件總空間,如果大於等於,就表示這次Minor GC是安全的,因為Minor GC後可能會出現把新生代物件儲存到老年代中的情況(當Minor GC後surviror空間記憶體不夠用時),如果這個條件不成立,那虛擬機會查看HandlePromotionFailure設定是否允許擔保失敗,允許的話,虛擬機會看老年代最大連續可用空間的大小是否大於歷次晉升到老年代的物件平均大小,如果大於,虛擬機會嘗試進行一次Minor GC。如果不允許擔保失敗,就會進行Full GC(老年代GC)來回收老年代死亡對象的空間好讓老年代騰出更大的空間。

#

以上是java中JVM記憶體如何分配與管理?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除