1. 程式人生 > >JVM(三) 堆記憶體的劃分

JVM(三) 堆記憶體的劃分

一、學習JVM的目的一般是出現記憶體異常的時候快速定位問題和效能優化,那麼記憶體是如何分配的就必須的作為基礎知識。在上一篇《執行時資料區》中描述的瞭解到其實執行緒獨佔的三部分gc基本不動,線上程共享的兩部分方法區gc也是基本動不了。那gc基本唯一會經常操作的就是堆記憶體。堆記憶體的大致劃分: JDK 1.8和以前 在這裡插入圖片描述 JDK 1.8以後 不在用永久帶,而是Meta Space已經不在堆記憶體中。 在這裡插入圖片描述 1.1 新生代 所有new的物件都在堆裡面。物件優先分配到Eden區,可以通過引數-XX:SurviviorRatio=8來指定Eden區和Survivior的比例,這樣劃分的依據和好處是根據gc的回收演算法來定的。做到了記憶體利用率高。 經過幾次(可以通過引數設定)minor gc還存活的物件進入S0,再經過幾次minor gc還存活進入S1,達到minor gc的閾值(-XX:MaxTenuringThreshold=?)進入老年代。 還有就是動態物件年齡判定,相同年齡所有物件的大小總和 > survivor空間的一半,直接晉級老年代,不需要進行年齡閾值的判斷。 這個區域的理想是98%以上的物件能夠被回收。 1.2 老年代 大物件(-XX:PretenureSizeThreadshold=1024)直接進入老年代,在新生代裡面長期存活的物件進入老年代。老年代對應的是major gc。 1.3 永久帶 包含元資料資訊,如class,method的detail資訊

二、空間分配擔保(就像貸款一樣) -XX:HandlerPromotionFailure Minor GC之前檢查 老年代最大可用連續空間是否 > 新生代所有物件總空間。 大於----> Minor GC 不大於—>老年代最大可用連續空間是否>歷次晉升到老年代物件的平均大小 大於-----> Minor GC 不大於 -----> Full GC -XX:HandlerPromotionFailure 注:Minor GC 是針對新生代的垃圾回收,MajorGC是老年代的,Full GC 是Minor GC 加上 MajorGC

三、物件的建立過程(new的過程) 在這裡插入圖片描述

3.1 怎麼在堆中分配記憶體 a,堆規整的前提下--------> 用指標碰撞 b,堆不規整的 ---------> 用空閒列表 堆規整不規整是由垃圾回收器的策略決定的 3.2 分配記憶體中執行緒安全的問題 比如多個執行緒同時new物件,那指標的位置歸誰? 解決辦法 1)同步加鎖 —效率低 2) 在堆中給每個執行緒分配區域。 3.3 物件的結構 a, Header:自身執行的資料(很多) b, InstanceDate 程式設計師寫的 c, Padding 3.4 物件的訪問定位 a,使用指標 hotspot 採用 b,使用控制代碼 (多一步操作,在堆中有控制代碼池。優點是棧中的地址不會變)