JVM知識點總覽:高階Java工程師面試必備
下面這篇文章彙集了阿里、美團、Oracle 等大廠的 JVM 考點,你是否能回答得上來?
- 什麼是 Java 虛擬機器?為什麼 Java 被稱作是“平臺無關的程式語言”?
- Java 程式碼是怎麼執行的?
- Java 虛擬機器是如何載入 Java 類的?
- JVM 執行記憶體的分類
- 如何監控和診斷 JVM 堆內和堆外記憶體使用?
- Java 四引用是什麼?
- 如何理解 JVM 內建的編譯或 GC 日誌?
- JVM 的永久代中會發生垃圾回收麼?
- Java 中的兩種異常型別是什麼?他們有什麼區別?
- JVM 是如何實現同步的?
- Java 內在模型是什麼?
- 即使編譯器有哪些優化?
- 在什麼情況下重複讀寫操作會被優化?
- 什麼樣的垃圾才被回收?
- 什麼時候會導致垃圾回收?
- 如何利用 JFR 和 JMC 監控 Java 程式?
- 如何利用 Unsafe API 繞開 JVM 的控制?
- 如何利用位元組碼注入為已有程式碼加料?
- ……
我挑選了幾個問題進行解答,希望能對大家面試起到幫助。
1、什麼是 Java 虛擬機器?為什麼 Java 被稱作是“平臺無關的程式語言”?
Java 虛擬機器是一個可以執行 Java 位元組碼的虛擬機器程式。Java 原始檔被編譯成能被 Java 虛擬機器執行的位元組碼檔案。
Java 被設計成允許應用程式可以執行在任意的平臺,而不需要程式設計師為每一個平臺單獨重寫或者是重新編譯。Java 虛擬機器讓這個變為可能,因為它知道底層硬體平臺的指令長度和其他特性。
2、Java 程式碼是怎麼執行的?
這個問題可以分三塊來回答:
- 為什麼 Java 要在虛擬機器裡執行?
- Java 虛擬機器具體是怎樣執行 Java 位元組碼的?
- Java 虛擬機器的執行效率究竟是怎麼樣的?
Java 之所以要在虛擬機器中執行,是因為它提供了可移植性。一旦 Java 程式碼被編譯為 Java 位元組碼,便可以在不同平臺上的 Java 虛擬機器實現上執行。此外,虛擬機器還提供了一個程式碼託管的環境,代替我們處理部分冗長而且容易出錯的事務,例如記憶體管理。
Java 虛擬機器將執行時記憶體區域劃分為五個部分,分別為方法區、堆、PC 暫存器、Java 方法棧和本地方法棧。Java 程式編譯而成的 class 檔案,需要先載入至方法區中,方能在 Java 虛擬機器中執行。
為了提高執行效率,標準 JDK 中的 HotSpot 虛擬機器採用的是一種混合執行的策略。首先,它會解釋執行 Java 位元組碼,然後會將其中反覆執行的熱點程式碼,以方法為單位進行即時編譯,翻譯成機器碼後直接執行在底層硬體之上。HotSpot 裝載了多個不同的即時編譯器,以便在編譯時間和生成程式碼的執行效率之間做取捨。
3、Java 虛擬機器是如何載入 Java 類的?
Java 虛擬機器將位元組流轉化為 Java 類的過程,可分為載入、連結以及初始化三大步驟。也可以用蓋房子來類比 Java 虛擬機器中的類載入。
載入是指查詢位元組流,並且據此建立類的過程。以蓋房子為例,村裡的 Tony 要蓋個房子,那麼按照流程他得先找個建築師,跟他說想要設計一個房型,比如說“一房、一廳、四衛”。這裡的房型相當於類,而建築師,就相當於類載入器。村裡有許多建築師,他們等級森嚴,但有著共同的祖師爺,叫啟動類載入器(boot class loader)。
載入需要藉助類載入器,在 Java 虛擬機器中,類載入器使用了雙親委派模型,即接收到載入請求時,會先將請求轉發給父類載入器。
連結,是指將建立成的類合併至 Java 虛擬機器中,使之能夠執行的過程。連結還分驗證、準備和解析三個階段。其中,解析階段為非必須的。
初始化,則是為標記為常量值的欄位賦值,以及執行方法的過程。類的初始化僅會被執行一次,這個特性被用來實現單例的延遲初始化。這放在我們蓋房子的例子中就是,只有當房子裝修過後,Tony 才能真正地住進去。
4、如何監控和診斷 JVM 堆內和堆外記憶體使用?
瞭解 JVM 記憶體的方法有很多,具體能力範圍也有區別,簡單總結如下:
可以使用綜合性的圖形化工具,如 JConsole、VisualVM(注意,從 Oracle JDK 9 開始,VisualVM 已經不再包含在 JDK 安裝包中)等。這些工具具體使用起來相對比較直觀,直接連線到 Java 程式,然後就可以在圖形化介面裡掌握記憶體使用情況。以 JConsole 為例,其記憶體頁面可以顯示常見的堆記憶體和各種堆外部分使用狀態。
也可以使用命令列工具進行執行時查詢,如 jstat 和 jmap 等工具都提供了一些選項,可以檢視堆、方法區等使用資料。
或者,也可以使用 jmap 等提供的命令,生成堆轉儲(Heap Dump)檔案,然後利用 jhat 或 Eclipse MAT 等堆轉儲分析工具進行詳細分析。
如果你使用的是 Tomcat、Weblogic 等 Java EE 伺服器,這些伺服器同樣提供了記憶體管理相關的功能。
另外,從某種程度上來說,GC 日誌等輸出,同樣包含著豐富的資訊。
這裡有一個相對特殊的部分,就是是堆外記憶體中的直接記憶體,前面的工具基本不適用,可以使用 JDK 自帶的 Native Memory Tracking(NMT)特性,它會從 JVM 本地記憶體分配的角度進行解讀。
5、JVM 的永久代中會發生垃圾回收麼?
垃圾回收不會發生在永久代,如果永久代滿了或者是超過了臨界值,會觸發完全垃圾回收 (Full GC)。如果你仔細檢視垃圾收集器的輸出資訊,就會發現永久代也是被回收的。這就是為什麼正確的永久代大小對避免 Full GC 是非常重要的原因。
(注:Java8 中已經移除了永久代,新加了一個叫做後設資料區的 native 記憶體區)
6、在 Java 中,物件什麼時候可以被垃圾回收?
當物件對當前使用這個物件的應用程式變得不可觸及的時候,這個物件就可以被回收了。
7、Java 中的兩種異常型別是什麼?他們有什麼區別?
Java 中有兩種異常:受檢查的 (checked) 異常和不受檢查的 (unchecked) 異常。不受檢查的異常不需要在方法或者是建構函式上宣告,就算方法或者是建構函式的執行可能會丟擲這樣的異常,並且不受檢查的異常可以傳播到方法或者是建構函式的外面。相反,受檢查的異常必須要用 throws 語句在方法或者是建構函式上宣告。還有一些 Java 異常處理的小建議,我的專欄裡都有提到。
8、JVM 垃圾回收演算法
標記 - 清除演算法:首先標記出所有需要回收的物件,在標記完成後統一回收所有被標記的物件。
複製演算法:將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當一塊記憶體用完了,將還存另外一塊上面,然後在把已使用過的記憶體空間一次清理掉。
標記 - 整理演算法:標記過程與“標記 - 清除”演算法一樣,但後續步驟不是直接對可回收物件進行清理,而是讓所一端移動,然後直接清理掉端邊界以外的記憶體。
分代收集演算法:一般是把 Java 堆分為新生代和老年代,根據各個年代的特點採用最適當的收集演算法。新生代都發現有大批物件死去,選用複製演算法。老年代中因為物件存活率高,必須使用“標記 - 清理”或“標記 - 整理”演算法來進行回收。
相關文章
- JAVA高階面試必過知識點彙總Java面試
- jvm系列(八):jvm知識點總覽JVM
- Redis 面試必備知識點Redis面試
- JVM-Java工程師必須掌握的知識點JVMJava工程師
- 高階 Java 面試通關知識點整理Java面試
- Python工程師面試必備25條知識點Python工程師面試
- java知識點-高階Java
- 高階 Java 必須突破的 10 個知識點!Java
- 高階Java必須突破的10個知識點!Java
- 前端進階必備知識彙總前端
- 面試總結——Java高階工程師面試Java工程師
- java面試知識點總結Java面試
- Java 面試知識點總結Java面試
- 最近Java高階工程師面試總結Java工程師面試
- 面試總結——Java高階工程師(二)面試Java工程師
- 面試總結——Java高階工程師(三)面試Java工程師
- 面試題總結 —— JAVA高階工程師面試題Java工程師
- JVM面試知識點梳理JVM面試
- 高階前端工程師面試必備(持續更新中)前端工程師面試
- Java面試題必備知識之ThreadLocalJava面試題thread
- 高階Java工程師必備 ----- 深入分析 Java IO (三)Java工程師
- css必備知識點CSS
- 必備知識點 路由路由
- 必備知識點 模版
- 騰訊 PHP 面試必備知識PHP面試
- 面試必知的web知識點面試Web
- Python入門必備知識點總結Python
- Java基礎面試知識點總結Java面試
- 常見Java面試知識點總結Java面試
- 高階Java工程師必備 ----- 深入分析 Java IO (二)NIOJava工程師
- Java常見知識點彙總(⑮)——Jvm架構JavaJVM架構
- 前端必備知識點—SVG前端SVG
- 必備知識點 檢視
- (小白學JAVA之)Java高階特性知識點梳理Java
- 多執行緒面試必備基礎知識彙總執行緒面試
- 成功應聘Java高階開發工程師必備的8大的面試考綱!Java工程師面試
- 掌握了這些Android高階工程師必備知識後,他拿到了 BAT OfferAndroid工程師BAT
- Android高階知識點Android