深刻Java虛擬機之 -- 總結面試篇

本文已受權玉剛說公衆號web

系列文章:面試

深刻Java虛擬機之 -- 總結面試篇算法

深刻Java虛擬機之 --- JVM的愛恨情仇安全

JAVA 垃圾回收機制(一) --- 對象回收與算法初識bash

JAVA 垃圾回收機制(二) --- GC回收具體實現app

深刻Java虛擬機之 -- 類文件結構(字節碼)學習

深刻Java虛擬機之 -- 類加載機制ui

在學習 JVM 相關知識,怎麼讓本身有動力看下去,且有思考性呢?筆者認爲,開頭用一些經常使用的面試題,來引入讀者的興趣比較好,這樣纔會有看下去的東西,因此,該篇文章會以面試+總結的方式,但願讀者能先思考寫出答案,再查看相關知識。spa

1、JVM常見面試題

深刻Java虛擬機之 -- 總結面試篇.net

  • 介紹下 Java 內存區域
  • Java 對象的建立過程
  • 對象的訪問定位有幾種
  • String、StringBuilder、StringBuffer 有什麼不一樣?

這是一些常見的面試,不少人都看到網上的標準答案,但你知道爲何嗎?

1.1 介紹下 Java 內存區域

首先看第一個,Java的內存區域,能夠看一張編譯圖:

能夠看到Java 的內存區域就是框框裏的東西,每一步的大概意思以下,具體細節參考 深刻Java虛擬機之 --- JVM的愛恨情仇
在這裏插入圖片描述
總結,建議讀者學習以後,能本身默寫這些方法並指導每一步的意思;

1.2 Java 對象的建立過程

Java 對象的建立共分爲5步,以下圖:

在這裏插入圖片描述
而後明白每一個步驟作了哪些便可,以下:
在這裏插入圖片描述

1.三、對象的訪問定位有幾種

有兩種方式:句柄和直接指針; 建立對象是爲了使用對象,虛擬機須要經過棧中的 reference 來獲取堆上的對象。

在這裏插入圖片描述
優缺點: 使用句柄好處是,當對象發生改變,只須要移動句柄的實例數據指針便可,而直接指針就是速度快。

1.4 String、StringBuilder、StringBuffer 有什麼不一樣

參考答案是: String 是用 final 修飾的類,因爲它的不可變性,相似拼接、裁剪字符串等,都會產生新的對象。 StringBuffer 解決上面拼接對象而提供一個類,能夠經過 append等方法拼接,是線程安全的,因爲線程安全,效率也降低 StringBuilder 跟StringBuffer 差很少,只是去掉了線程安全,因此優先使用 StringBuilder

說說String 爲何會產生新的對象?好比 String a = "1" String b = a + "2",當執行這條指令時,會在常量池中產生一個對象指向a,而建立b時也會從新在常量池中生成b的對象;屢次建立容易觸發 GC,這也是爲何不建議使用 String 類去拼接的問題。

2、Java 回收機制常見面試題

深刻Java虛擬機之 --- JVM的愛恨情仇 JAVA 垃圾回收機制(二) --- GC回收具體實現

  • 簡單的介紹一下強引用、軟引用、弱引用、虛引用(虛引用與軟引用和弱引用的區別、使用軟引用能帶來的好處)
  • 談談final、finally、finalize 有什麼不一樣
  • 方法區會回收資源嗎?
  • 垃圾回收有哪些算法,各自的特色?

2.1 簡單的介紹一下強引用、軟引用、弱引用、虛引用

首先,在講解這幾個引用以前,先明白虛擬機爲何會由這些引用的說明;咱們都知道,對象須要回收,那怎麼去判斷哪些對象須要回收呢?這就須要一些判斷來肯定哪些對象是須要回收的,通常有如下幾種方法:

在這裏插入圖片描述
不管是 引用計算算法仍是可達性分析算法,都是涉及到對象的引用問題,因此,在 JDK1.2 以後,又分爲如下幾類引用:
在這裏插入圖片描述
經過上面的介紹,知道了" 引用"是什麼關係,這對理解各類引用仍是頗有必要的,那麼使用 軟引用的好處也在那裏了; 建議一些內存消耗較大的使用軟引用,好比 webview。。

2.2 談談final、finally、finalize 有什麼不一樣

final 和finally 比較好理解。首先 final 用來修飾的對象不可變;finally 則是保證重點代碼必定要被執行的一種機制,通常用於 try - catch-finally 語句中。 但finalize 是什麼東西呢?在解釋標準代碼以前,又得回到GC算法中了。 首先,finalize 是 Object 的一個方法,用來特定資源的回收。 上面說到,當 GC Roots 不可達時,認爲對象已經再也不使用了,可是對象並不是是非"死"不可,當 GC Roots 不可達時,系統首先會先判斷 對象的 finalize 是否執行,不執行則直接回收;若是能夠執行,則放在隊列中,由finalize線程去執行它,若是有其餘對象關聯時,則判斷對象不可回收,不然對象回收,finalize 執行一次,以下圖:

在這裏插入圖片描述
因爲它的不肯定性,在 JDK9時,已經標註爲deprecated,但不影響咱們對它的理解。

2.3 方法區會回收資源嗎?

雖然說 Java 堆 能夠回收70%~95%的空間,但方法區一樣能夠回收一些資源,方法區主要回收兩個部分廢棄常量無用的類

在這裏插入圖片描述
因此,當發生 GC 時,很是常量和無用類是能夠被回收,固然這裏也是說"能夠",是否像對象同樣被回收,還須要對虛擬機的參數配置,這裏就不細說了。

2.4 垃圾回收有哪些算法,各自的特色?

對象的回收,基於上面講到的,GC Roots不可達,且判斷能夠回收。衍生的算法以下圖(建議能默認每種算法的理解):

在這裏插入圖片描述
其中,基礎是 標記-清除是基礎,接下來都是在它的基礎上改進,分代算法是主流 Java 虛擬機的主要算法; 其中各個算法特色以下,詳細介紹看 JAVA 垃圾回收機制(一) --- 對象回收與算法初識 第四節,垃圾回收篇。
在這裏插入圖片描述
關係新生代和老年代的問題,參考: JAVA 垃圾回收機制(二) --- GC回收具體實現

3、類加載的問題

深刻Java虛擬機之 -- 類文件結構(字節碼) 深刻Java虛擬機之 -- 類加載機制

  • 類加載過程
  • 寫出下列代碼打印信息,若將改爲System.out.println(Child.c_value);改成System.out.println(Child.value); 如何?
public class Parent{
   static {
   	System.out.println("Parent");
   }
   public static int value = 123;
}

public class Child extends Parent{
   static {
   	System.out.println("Child");
   }
   public static int c_value = 123;
}

//mian 中執行
public static void main(String[] args) {
   System.out.println(Child.c_value);
}
複製代碼
  • 說說你對類加載器的理解
  • 什麼是雙親委派模型

3.1 類加載的過程

類加載的過程以下圖所示(建議能默認每一個步驟的理解):

在這裏插入圖片描述
也能夠成爲 加載-鏈接-初始化 這種叫法。 其中, 加載、驗證、準備、初始化和卸載的順序是固定的,而解析則不必定,由於Java是動態語言,它能夠在運行時解析,即初始化以後。該階段解析以下:
在這裏插入圖片描述

3.2 寫出下列代碼打印信息,若將改爲System.out.println(Child.c_value);改成System.out.println(Child.value); 如何?

public class Parent{
   static {
   	System.out.println("Parent");
   }
   public static int value = 123;
}

public class Child extends Parent{
   static {
   	System.out.println("Child");
   }
   public static int c_value = 123;
}

//mian 中執行
public static void main(String[] args) {
   System.out.println(Child.c_value);
}
複製代碼

打印信息如:

Parent
Child
123
複製代碼

改成System.out.println(Child.value)時:

Parent
123
複製代碼

具體看:深刻Java虛擬機之 -- 類加載機制 擴展

class Parent{
		public static int value = 1;
		static {
			value = 2;
		}
	}
	
class Child extends Parent{

	public static int B = value ;
}


public static void main(String[] args) {
	System.out.println(Child.B);
}
複製代碼

輸出什麼?

3.3 說說你對類加載器的理解

從上面咱們知道,類在加載的時候,就是經過一個全限定名去加載這個類的二進制字節流,這個是系統自動完成的。這個動做若是從外部去作,以便於咱們去獲取所需的類,則咱們成爲類加載器。好比經過一個路徑獲取到一個 class 字節碼,而後經過反射,拿到相應的信息。

3.4 什麼是雙親委派模型

它的工程流程是: 當一個類加載器收到類加載的請求,它首先不會本身去嘗試加載這個類,而是委派給她的父類加載器去完成,每個層次的類加載器都是如此,所以全部的加載器都會傳遞到父加載器中;只有父加載器沒法完成時,子加載器纔會嘗試本身去加載,它的模型以下:

類加載雙親委派模型
相關文章
相關標籤/搜索