Java自動(dòng)內(nèi)存管理

JVM? HotSpot 虛擬機(jī), JRockit,IBM J9, [ Android Dalvik,? ART(Android Runtime)? ]

內(nèi)存

JVM數(shù)據(jù)區(qū)

程序計(jì)數(shù)器: 當(dāng)前線程執(zhí)行的字節(jié)碼指令的地址,執(zhí)行Native方法時(shí)為空

虛擬機(jī)棧: 局部變量表 方法出口等

異常: StackOverflowError? OutOfMemoryError

-Xss1m

本地方法棧: 執(zhí)行Native方法的棧

異常: StackOverflowError? OutOfMemoryError

-Xoss1m (HotSpot不生效)

: 對象和數(shù)組在堆上分配(有例外,JIT優(yōu)化),垃圾回收, 物理上可以不連續(xù)

異常: OutOfMemoryError? ? Java Heap Space

-Xms256m? -Xmx1024m

方法區(qū): 類信息、常量、靜態(tài)變量、JIT編譯后代碼, 也叫Non-Heap(非堆)

Java7、8 廢棄了永久代

異常:OutOfMemoryError

直接內(nèi)存:DirectMemory, 非JVM數(shù)據(jù)區(qū)

異常:OutOfMemoryError

注:java.nio.DirectByteBuffer受 -XX:MaxDirectMemorySize=256m 限制,默認(rèn)為-Xmx

對象

對象創(chuàng)建

1、檢查類加載

2、分配內(nèi)存:指針碰撞? 空閑列表, 取決于內(nèi)存是否規(guī)整

并發(fā):CAS失敗重試? ? 本地線程分配緩沖TLAB? -XX:+/-UseTLAB

3、初始化為0值,設(shè)置對象頭,引用入棧,執(zhí)行<init>方法

對象內(nèi)存布局: 對象頭、實(shí)例數(shù)據(jù)、對齊填充

對象頭:1、運(yùn)行時(shí)數(shù)據(jù):hashCode? GC分代年齡? 鎖信息? ?

(2、類型指針)

(3、數(shù)組長度)

對象訪問定位:句柄、直接指針

垃圾收集 GC

哪些內(nèi)存需要回收?

什么時(shí)候回收?

如何回收?

衡量指標(biāo)

內(nèi)存占用? 吞吐量? 延遲

分配內(nèi)存效率


1、引用計(jì)數(shù):? 循環(huán)引用問題? (如 Python? COM)

2、可達(dá)性分析? (如 Java? Go? C#)

GCRoot:棧引用、靜態(tài)變量引用、常量引用、虛擬機(jī)內(nèi)部引用等

引用類型

強(qiáng)引用 Strongly:不回收

軟引用 Soft: 內(nèi)存溢出時(shí)回收

弱引用 Weak:GC時(shí)一定會(huì)回收

虛引用 Phantom:不能通過虛引用獲取對象實(shí)例,用于回收時(shí)接收通知

方法區(qū)的回收

廢棄的常量和不再使用的類型

分代收集

將Java堆劃分出不同的區(qū)域, 對象依據(jù)年齡分配的不同的區(qū)域中

弱分代假說:絕大多數(shù)對象都是朝生夕滅的

強(qiáng)分代假說:熬過越多次垃圾收集過程的對象就越難以消亡

跨代引用假說:跨代引用相對于同代引用來說僅占極少數(shù)。

部分收集(Partial GC): 收集部分Java堆,分為:

1、新生代收集(Minor GC/Young GC):指目標(biāo)只是新生代的垃圾收集。

2、老年代收集(Major GC/Old GC):指目標(biāo)只是老年代的垃圾收集。目前只有CMS收集器會(huì)有單獨(dú)收集老年代的行為。另外請注意“Major GC”這個(gè)說法現(xiàn)在有點(diǎn)混淆,在不同資料上常有不同所指,讀者需按上下文區(qū)分到底是指老年代的收集還是整堆收集。

3、混合收集(Mixed GC):指目標(biāo)是收集整個(gè)新生代以及部分老年代的垃圾收集。目前只有G1收集器會(huì)有這種行為。

整堆收集(Full GC):收集整個(gè)Java堆和方法區(qū)的垃圾收集。


標(biāo)記清除 Mark-Sweep

標(biāo)記復(fù)制

半?yún)^(qū)復(fù)制 Semispace Copying

appel式回收

Eden : Survivor : Survivor = 8 : 1 : 1

在Eden和一個(gè)Survivor分配對象,收集時(shí)復(fù)制到另一個(gè)Survivor,空間不足則進(jìn)入老年代

標(biāo)記整理? Mark-Compact

根節(jié)點(diǎn)枚舉

安全點(diǎn)? ? Stop The World

安全區(qū)域

記憶集與卡表? ? 跨代引用問題

寫屏障

并發(fā)的可達(dá)性分析

三色標(biāo)記? 對象消失問題? 增量更新? 原始快照

經(jīng)典收集器

并行(Parallel):多個(gè)垃圾收集器線程并行

并發(fā)(Concurrent):垃圾收集器線程與用戶線程

用于客戶端模式

吞吐量優(yōu)先

CMS(Concurrent Mark Sweep): 并發(fā) 低停頓

初始標(biāo)記(CMS initial mark)? Root

并發(fā)標(biāo)記(CMS concurrent mark)? 并發(fā)

重新標(biāo)記(CMS remark)? 增量更新

并發(fā)清除(CMS concurrent sweep)? 并發(fā)

G1(Garbage First)

初始標(biāo)記(Initial Marking)? Root

并發(fā)標(biāo)記(Concurrent Marking)? ? 并發(fā)

最終標(biāo)記(Final Marking)

篩選回收(Live Data Counting and Evacuation)

Shenandoah

不分代? 記憶集改為連接矩陣

初始標(biāo)記(Initial Marking)? root

并發(fā)標(biāo)記(Concurrent Marking)? 并發(fā)

最終標(biāo)記(Final Marking)

并發(fā)清理(Concurrent Cleanup)? 并發(fā)? 清理沒有存活對象的區(qū)域

并發(fā)回收(Concurrent Evacuation)? ? 并發(fā)? ? 讀屏障? 轉(zhuǎn)發(fā)指針

初始引用更新(Initial Update Reference)

并發(fā)引用更新(Concurrent Update Reference)? 并發(fā)

最終引用更新(Final Update Reference)? ? 更新 root 引用

并發(fā)清理(Concurrent Cleanup)

ZGC

基于Region內(nèi)存布局的,(暫時(shí))不設(shè)分代的,使用了讀屏障、染色指針和內(nèi)存多重映射等技術(shù)來實(shí)現(xiàn)可并發(fā)的標(biāo)記-整理算法的,以低延遲為首要目標(biāo)的一款垃圾收集器

小型Region(Small Region):容量固定為2MB,用于放置小于256KB的小對象。

中型Region(Medium Region):容量固定為32MB,用于放置大于等于256KB但小于4MB的對象。

大型Region(Large Region):容量不固定,可以動(dòng)態(tài)變化,但必須為2MB的整數(shù)倍,用于放置4MB或以上的大對象。最小容量為4MB。

染色指針: 指針前4位記錄三色標(biāo)記、被移動(dòng)信息

虛擬內(nèi)存映射

并發(fā)標(biāo)記(Concurrent Mark):更新染色指針中的Marked 0、Marked 1標(biāo)志位

并發(fā)預(yù)備重分配(Concurrent Prepare for Relocate):統(tǒng)計(jì)得出本次收集過程要清理哪些Region

并發(fā)重分配(Concurrent Relocate):存活對象復(fù)制到新的Region上,維護(hù)轉(zhuǎn)發(fā)表,指針的“自愈”(Self-Healing)

并發(fā)重映射(Concurrent Remap):修正所有引用,釋放轉(zhuǎn)發(fā)表,合并到下一次并發(fā)標(biāo)記

“NUMA-Aware”的內(nèi)存分配

Epsilon

只分配不回收,用于微服務(wù)

CG參數(shù)

日志級別? ? Trace,Debug,Info,Warning,Error,Off

GC日志? java9-? ? java9+

GC基本信息? ? -XX:+PrintGC? ? ? -Xlog:gc

GC詳細(xì)信息? ? -XX:+PrintGCDetails? ? ? ? -Xlog:gc*

參數(shù)自動(dòng)設(shè)置? -XX:+PrintAdaptiveSizePolicy? ? -Xlog:gc+ergo*=trace

并發(fā)/停頓時(shí)間? ? -XX:+PrintGCApplicationConcurrentTime

-XX:+PrintGCApplicationStoppedTime? ? ? ? -Xlog:safepoint

-XX:+UseG1GC

-XX:+UnlockExperimentalVMOptions

-XX:+UseZGC? ?

-XX:+UseShenandoahGC? ? ? AdoptOpenJDK? HotSpot

-showversion? 查看java版本

-XX:+PrintCommandLineFlags? ? 查看參數(shù)設(shè)置

-XX:+PrintFlagsInitial? --查看出廠默認(rèn)值

-XX:+PrintFlagsFinal? --查看修改更新? (= 沒有修改過? := 人為修改過)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容