java虛擬機全家桶

一 內存劃分
1 finanlize() 方法工作原理
一個對象被回收要經過2次標記。如果對象沒有執行過finalize方法且覆蓋了finalize方法,則會進行第一次標記存放到F-Queue隊列中;第二次標記是執行finalize()方法時,如果在方法中對象重新與類引用或者方法引用關聯上,則可以逃離這次回收。

2 jdk1.8內存分代改進
永久代用元空間來替代

3 java內存劃分
在這裏插入圖片描述

程序計數器: 保存每個線程下一個指令的指針,保證線程切換回來後能接着執行, 不會出現oom
虛擬機棧: 作用於方法層級,爲每個線程分配局部變量副本, 存儲基礎數據類型和引用, 可能出現
stackofoverError oom
本地方法棧:和虛擬機棧類似,只是針對的是native方法
方法區: 永久代,存儲類的變量、常量、靜態塊,可能出現oom
堆:對象存儲的地方,gc一般在這裏活動,可能出現oom異常,分成新生代和老年代

二 內存溢出
1 分別寫出堆溢出和棧溢出的程序
棧溢出:

public void f() {
    f();
}

堆溢出:

public void testd() {
    List<String> list = new ArrayList<>();
    int i = 0;

    while (true) {
        list.add(new String(i + ""));
        i++;
    }
}

三 垃圾回收機制
1 強引用、軟引用、弱引用、虛引用的簡介,他們和gc的關係?
強引用:最常見的,類似 Object obj = new Object(); 只要引用還存在,gc就不會回收掉引用的對象
軟引用:還有用但並非是必要的對象,在系統內存溢出之前,會把這類對象列入到回收範圍,進行第二次回收
弱引用:比軟引用更弱一層,被弱引用關聯的對象只能生存到下一次gc之前
虛引用:最弱的一種引用關係,完全不會對關聯對象的生命週期造成影響。目的是對象回收時能收到系統的通知

2 jvm垃圾回收機制,何時出發MinorGC等操作?
eden區無法爲一個新對象分配內存時

3 對象如何晉升爲老年代
1)大對象直接進入老年代
2)年齡達到閥值也會進入老年代,虛擬機爲每個在s區的對象分配一個年齡計數器,每熬過一次gc沒被回收,年齡加1,達到年齡上限就會進入老年代
3)s區中相同年齡的對象大小超過了s區的一半以上,則大於等於這個年齡的對象都會進入老年代
4)垃圾回收後,存活的對象大小超過了s區的大小,會把一部分對象擔保到老年代中

4 eden區和survivor區的比例分配
jdk1.7是8:1
jdk1.8是6:1

5 垃圾回收算法
標記-清除算法: 最基礎的算法,其他算法依據此算法優化
複製算法: 適用於新生代
標記-整理算法:適用於老年代,把存活的對象整理到一端,清除掉邊界外的內存
分代整理: 新生代和老年代分別使用適合的算法進行回收

6 System.gc() 和 Runtime.gc() 會做什麼事情?
1)java.lang.System.gc()只是java.lang.Runtime.getRuntime().gc()的簡寫,兩者的行爲沒有任何不同
2)System.gc()和runtime.gc()用於提示jvm進行垃圾回收,但是否立即回收還是延遲迴收由java虛擬機決定

四 類加載機制
1 Class.forName()和ClassLoader.loadClass()區別
Class.forName()涉及了類加載過程的:加載、驗證、準備、解析、初始化 5個過程
ClassLoader.loadClass()只涉及了類加載過程的加載動作,後面的動作都不會執行

2 什麼是類的雙親委派模型
在這裏插入圖片描述

類加載時,先用父類加載器嘗試加載,一層層往上,最後會讓啓動類加載器嘗試加載,能加載就被父類加載器加載了。如果父類加載器不能加載,纔會讓子類加載器加載。

雙親委派模型的目的: 保證了同一個類只能被同一個類加載器加載

3 類加載過程

加載、驗證、準備、解析、初始化
在這裏插入圖片描述
加載:把class轉成二進制字節流
驗證:保證字節流是虛擬機需要的,有:文件格式驗證、類、方法驗證、符號引用驗證
準備:類變量設置初始值
解析:把符號引用轉成直接引用
初始化:類變量和靜態塊初始成預期的值

4 描述一下 JVM 加載 Class 文件的原理機制?
JVM中類的加載是有ClassLoader和他的子類來實現的,負責把Class文件加載到內存中。
類加載方式有兩種:
1)隱式加載:程序運行時遇到new生成對象時,隱式調用類加載器加載對應的類到jvm中
2)顯示加載:通過Class.forName()等方式,顯示加載需要的類

 Java類的加載是動態的,它並不會一次性將所有類全部加載後再運行,而是保證程序運行的基礎類(像是基類)完全加載到jvm中,至於其他類,則在需要的時候才加載。這當然就是爲了節省內存開銷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章