更新時間:2019-10-18 14:15:16 來源:動力節點 瀏覽2477次
下面這篇文章匯集了阿里、美團、Oracle等大廠的JVM考點,你是否能回答得上來?
什么是Java虛擬機?為什么Java被稱作是“平臺無關的編程語言”?
Java代碼是怎么運行的?
Java虛擬機是如何加載Java類的?
JVM運行內存的分類
如何監控和診斷JVM堆內和堆外內存使用?
Java四引用是什么?
如何理解JVM內置的編譯或GC日志?
JVM的永久代中會發生垃圾回收么?
Java中的兩種異常類型是什么?他們有什么區別?
JVM是如何實現同步的?
Java內在模型是什么?
即使編譯器有哪些優化?
在什么情況下重復讀寫操作會被優化?
什么樣的垃圾才被回收?
什么時候會導致垃圾回收?
如何利用JFR和JMC監控Java程序?
如何利用UnsafeAPI繞開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要蓋個房子,那么按照流程他得先找個建筑師,跟他說想要設計一個房型,比如說“一房、一廳、四衛”。這里的房型相當于類,而建筑師,就相當于類加載器。村里有許多建筑師,他們等級森嚴,但有著共同的祖師爺,叫啟動類加載器(bootclassloader)。
加載需要借助類加載器,在Java虛擬機中,類加載器使用了雙親委派模型,即接收到加載請求時,會先將請求轉發給父類加載器。
鏈接,是指將創建成的類合并至Java虛擬機中,使之能夠執行的過程。鏈接還分驗證、準備和解析三個階段。其中,解析階段為非必須的。
初始化,則是為標記為常量值的字段賦值,以及執行
4、如何監控和診斷JVM堆內和堆外內存使用?
了解JVM內存的方法有很多,具體能力范圍也有區別,簡單總結如下:
可以使用綜合性的圖形化工具,如JConsole、VisualVM(注意,從OracleJDK9開始,VisualVM已經不再包含在JDK安裝包中)等。這些工具具體使用起來相對比較直觀,直接連接到Java進程,然后就可以在圖形化界面里掌握內存使用情況。以JConsole為例,其內存頁面可以顯示常見的堆內存和各種堆外部分使用狀態。
也可以使用命令行工具進行運行時查詢,如jstat和jmap等工具都提供了一些選項,可以查看堆、方法區等使用數據。
或者,也可以使用jmap等提供的命令,生成堆轉儲(HeapDump)文件,然后利用jhat或EclipseMAT等堆轉儲分析工具進行詳細分析。
如果你使用的是Tomcat、Weblogic等JavaEE服務器,這些服務器同樣提供了內存管理相關的功能。
另外,從某種程度上來說,GC日志等輸出,同樣包含著豐富的信息。
這里有一個相對特殊的部分,就是是堆外內存中的直接內存,前面的工具基本不適用,可以使用JDK自帶的NativeMemoryTracking(NMT)特性,它會從JVM本地內存分配的角度進行解讀。
5、JVM的永久代中會發生垃圾回收么?
垃圾回收不會發生在永久代,如果永久代滿了或者是超過了臨界值,會觸發完全垃圾回收(FullGC)。如果你仔細查看垃圾收集器的輸出信息,就會發現永久代也是被回收的。這就是為什么正確的永久代大小對避免FullGC是非常重要的原因。
(注:Java8中已經移除了永久代,新加了一個叫做元數據區的native內存區)
6、在Java中,對象什么時候可以被垃圾回收?
當對象對當前使用這個對象的應用程序變得不可觸及的時候,這個對象就可以被回收了。
7、Java中的兩種異常類型是什么?他們有什么區別?
Java中有兩種異常:受檢查的(checked)異常和不受檢查的(unchecked)異常。不受檢查的異常不需要在方法或者是構造函數上聲明,就算方法或者是構造函數的執行可能會拋出這樣的異常,并且不受檢查的異常可以傳播到方法或者是構造函數的外面。相反,受檢查的異常必須要用throws語句在方法或者是構造函數上聲明。還有一些Java異常處理的小建議,我的專欄里都有提到。
8、JVM垃圾回收算法
標記-清除算法:首先標記出所有需要回收的對象,在標記完成后統一回收所有被標記的對象。
復制算法:將可用內存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當一塊內存用完了,將還存另外一塊上面,然后在把已使用過的內存空間一次清理掉。
標記-整理算法:標記過程與“標記-清除”算法一樣,但后續步驟不是直接對可回收對象進行清理,而是讓所一端移動,然后直接清理掉端邊界以外的內存。
分代收集算法:一般是把Java堆分為新生代和老年代,根據各個年代的特點采用最適當的收集算法。新生代都發現有大批對象死去,選用復制算法。老年代中因為對象存活率高,必須使用“標記-清理”或“標記-整理”算法來進行回收。
以上就是動力節點java培訓機構小編介紹的“JVM考點:高級Java工程師面試必備”的內容,希望對大家有幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。
相關推薦
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習