JVM 內存分配與回收策略

Java 中,對象的內存分配,大的方向講,就是在堆上分配。對象主要分配在新生代的eden區上。

內存分配規則:

大多數情況,內存在新生代eden區中分配,當eden區沒有足夠空間進行分配的時候,虛擬機將發起一次minor GC

大對象直接進入老年代:

首先需要知道什麼是大對象:

大對象: 需要大量連續內存空間的JAVA 對象 ,典型的大對象就是那種很長的字符串以及數組。 大對象對於虛擬機的內存分配來說是個很壞的消息,經常出現大對象容易導致內存中還有不少空間的時候就需要提前觸發垃圾回收來獲取更多的連續空間
虛擬機提供了一個 -XX:PretenureSizeThreshold 參數,大於這個設置值的對象直接在老年代中進行內存分配, 這樣做的母的在於避免新生代發生大量的內存複製

長期存活的對象進入老年代:

虛擬機給每一個對象定義了一個對象年齡計數器。如果對象在Eden 區出生,經過第一次新生代GC 仍然存在,並且能夠被Survivor 容納的,那麼將會移動到Survivor 空間,並且對象年齡設置爲1 ,對於Survivor 區中的對象,只要每進過一次新生代GC ,對象年齡就增長一歲,當對象年齡到達晉升老年代的閾值(可以自己設置) 那麼對象就會被晉升到老年代。

動態對象的年齡判定:

爲了更好的適應不同程序的內存情況,虛擬機並不是永遠的要求年齡必須達到閾值才能晉升爲老年代,虛擬機會根據survivor裏面相同年齡的所有對象大小的綜合大於survivor大小的一半,年齡大於或等於該年齡的對象就可以直接進入老年代

空間分配擔保:

在發生新生代GC 的時候,虛擬機會區檢查老年代的連續空間大小是否大於新生代所有對象總空間,如果成立,那麼就可以確定新生代GC 行爲是安全的,但是如果小於,那麼就需要查看是否允許擔保失敗,如果允許,繼續檢查新生代需要晉升的對象的大小是否小於老年代的可用連續空見,如果大於,嘗試進行新生代GC ,如果小於或者不允許進行擔保失敗,那麼新生代GC 就會變成老年代 GC

總結:

內存回收和來及收集器很多時候都是影響系統性能,併發能力的主要因素之一,只有根據實際應用需求,實現方式選擇最優的蒐集方式才能獲取最高的性能。在實際的虛擬機調優階段,必須瞭解具體收集器的行爲,優勢和劣勢,以及調節參數,根據程序的實際情況進行調優

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章