一、JVM記憶體劃分
方法區(持久代):存放要加載的類資訊、類中靜态變量、final常量、方法資訊等;class對象的getname,isInterface等資料都來源于方法區。sun jdk中對應permanet generation
堆:預設實體記憶體的1/64。
本地方法棧:用于支援native方法的執行,存儲了每個native方法調用的狀态,sun jdk實作的中本地方法棧和jvm方法棧是同一個。
pc寄存器和jvm方法棧:每個線程會建立pc寄存器和jvm方法棧,pc寄存器可能占用cpu寄存器或作業系統記憶體,jvm方法棧占用作業系統記憶體。當jvm方法棧空間不足,會抛出stackoverflowerror,可通過-Xss配置。
二、記憶體配置設定
堆線程共享,是以堆配置設定記憶體空間時需要枷鎖。
sun jdk為提升記憶體配置設定效率,為每個建立線程在eden space單獨配置設定空間(thread local allocation buffer tlab),大小由jvm根據運作情況計算得到,可通過-XX:TLABWasteTargetPercent設定每個線程占eden space的百分比。
三、記憶體回收
通常采用收集器方式實作GC:
引用計數收集器:當計數器為零,說明對象已不再被使用,可回收。對循環調用不适合。
跟蹤收集器:全局記錄資料引用狀态,基于一定條件觸發(定時、空見不足),執行是從根集合掃描對象引用關系。
算法有:
複制:從根集合掃描存活對象,将其複制到新的未使用的空間中取。
标記-清除:從根集合掃描存活對象,對其進行标記。完畢後,掃描整個空間中未标記對象,進行回收。因直接回收不引用對象,會造成記憶體碎片。
标記-壓縮:在标記-清除的基礎上,将存活對象往左端空閑空間移動,并更新引用其對象的指針。
四、可用GC
1、串行GC(Serial GC)
根集合對象:目前運作線程棧上引用的對象、常量、靜态變量、傳到本地方法中還未被本地方法釋放的對象引用加上下面的remember me。
remember me:針對舊生代引用新生代對象情況設定,當進行對象指派是,若指派為一個對象引用,則産生write barrier,然後檢查需指派的對象是否在舊生代及指派的對象引用是否指向新生代,若滿足條件,則在remember set做标記。sun jdk使用card table實作remember me。
2、并行回收GC(Parallel Scavenge)
3、并行GC(ParNew)