更新時間:2023-01-30 15:47:26 來源:動力節點 瀏覽2068次
1.JVM內存模型
整體描述上面對運行時數據區描述了很多,其實重點存儲數據的是堆和方法區(非堆),所以內存的設計也著重從這兩方面展開(注意這兩塊區域都是線程共享的)。對于虛擬機棧,本地方法棧,程序計數器都是線程私有的
(1) 一塊是非堆區,一塊是堆區
(2) 堆區分為兩大塊:一個是old區,一個是Young區
(3) Young區分為兩大塊: 一個是survivor區 (S+S1) ,一塊是Eden區
(4) S和S1一樣大,也可以叫From和To
2.JVM使用“類”的生命周期是:
裝載、鏈接、初始化、使用、卸載
1.裝載:
定要找到Class文件所在的全路徑,然后裝載到內存中J,ava又是一門面向對象的開發語這個過程用到了類加載器 ClassLoader。
2.連接 該階段又包含了驗證、準備和解析3個過程,如下。
(1)驗證
校驗.class文件的正確性。
(2)準備
2.1給static靜態變量分配內存,并初始化static的默認值。
private static int a=10; 此時a變量會被賦值為默認值
2.2符號引用和直接引用
符號引用:4f62 6a65 6374 ----->loading 二進制流是沒有辦法被cpu直接解析的 (.class 變量 方法等等里面全是二進制的)
直接應用:0x00ab---0x00ba 物理內存
3.初始化:給static變量 賦予實際的值
private static int a=10; a=10;
4.使用:對象的初始化、對象的垃圾回收、對象的銷毀.
3、GC Roots 有哪些?
1、 GC Roots 是一組必須活躍的引用。用通俗的話來說,就是程序接下來通過直接引用或者間接引用,能夠訪問到的潛在被使用的對象。
2、 GC Roots 包括:Java 線程中,當前所有正在被調用的方法的引用類型參數、局部變量、臨時值等。也就是與我們棧幀相關的各種引用。所有當前被加載的 Java 類。Java 類的引用類型靜態變量。運行時常量池里的引用類型常量(String 或 Class 類型)。JVM 內部數據結構的一些引用,比如 sun.jvm.hotspot.memory.Universe 類。用于同步的監控對象,比如調用了對象的 wait() 方法。JNI handles,包括 global handles 和 local handles。
3、 這些 GC Roots 大體可以分為三大類,下面這種說法更加好記一些:活動線程相關的各種引用。類的靜態變量的引用。JNI 引用。
4、 有兩個注意點:我們這里說的是活躍的引用,而不是對象,對象是不能作為 GC Roots 的。GC 過程是找出所有活對象,并把其余空間認定為“無用”;而不是找出所有死掉的對象,并回收它們占用的空間。所以,哪怕 JVM 的堆非常的大,基于 tracing 的 GC 方式,回收速度也會非常快。
4.垃圾收集算法進行垃圾收集
標記-清除算法
分為標記和清除階段,首先從每個 GC Roots 出發依次標記有引用關系的對象,最后清除沒有標記的對象。
執行效率不穩定,如果堆包含大量對象且大部分需要回收,必須進行大量標記清除,導致效率隨對象數量增長而降低。
存在內存空間碎片化問題,會產生大量不連續的內存碎片,導致以后需要分配大對象時容易觸發 Full GC。
標記-復制算法
為了解決內存碎片問題,將可用內存按容量劃分為大小相等的兩塊,每次只使用其中一塊。當使用的這塊空間用完了,就將存活對象復制到另一塊,再把已使用過的內存空間一次清理掉。主要用于進行新生代。
實現簡單、運行高效,解決了內存碎片問題。代價是可用內存縮小為原來的一半,浪費空間。
HotSpot 把新生代劃分為一塊較大的 Eden 和兩塊較小的 Survivor(s0,s1),每次分配內存只使用 Eden 和其中一塊 Survivor(s0和s1 永遠只有一個有值)。垃圾收集時將 Eden 和 Survivor 中仍然存活的對象一次性復制到另一塊 Survivor 上,然后直接清理掉 Eden 和已用過的那塊 Survivor。HotSpot 默認Eden 和 Survivor 的大小比例是 8:1,即每次新生代中可用空間為整個新生代的 90%。
標記-整理算法
標記-復制算法在對象存活率高時要進行較多復制操作,效率低。如果不想浪費空間,就需要有額外空間分配擔保,應對被使用內存中所有對象都存活的極端情況,所以老年代一般不使用此算法。
老年代使用標記-整理算法,標記過程與標記-清除算法一樣,但不直接清理可回收對象,而是讓所有存活對象都向內存空間一端移動,然后清理掉邊界以外的內存。
標記-清除與標記-整理的差異在于前者是一種非移動式算法而后者是移動式的。如果移動存活對象,尤其是在老年代這種每次回收都有大量對象存活的區域,是一種極為負重的操作,而且移動必須全程暫停用戶線程。如果不移動對象就會導致空間碎片問題,只能依賴更復雜的內存分配器和訪問器解決。
以上就是“Java jvm類面試題,超級詳細的整理”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習