對於Java程式設計師來說,JVM是面試過程中必備考題之一,只要我們掌握了其核心知識點,萬變不離其中,無論怎麼考你,都能應對自如。這篇文章我會根據在實際面試過程中遇到的考題,然後結合理論知識點,總結一下JVM的實戰考點。
一、JVM總體知識點
JVM的考點總體為分4大塊:
1.類的加載機制
2.JVM的內存結構
3.GC(包括GC算法,垃圾回收器)
4.JVM調優化
下面就這4方面的知識點分別進行歸納總結。
二、類的加載機制
類的加載過程是指將java編譯之後的class文件讀入到內存中,然後在堆區創建一個java.lang.Class對象,用於封裝類在方法區內的數據結構。類加載的最終目的是封裝類在方法區的數據結構,並向java程式設計師提供訪問方法區數據的接口。
這裡要理解類的加載過程就要先了解一下類的生命周期:
類的生命周期一共分為5個階段,加載、連接、初始化、使用、卸載。
加載:類的加載過程主要完成3件事件,1.通過類的全限定名來獲取定義此類的二進位字節流,2.將這個類字節流代表的靜態存儲結構轉為方法區的運行時數據結構,3.在堆中生成一個代表此類的java.lang.Class對象,作為訪問方法區這些數據結構的入口。這個過程主要是類加載器完成的。
連接:這個過程分3個階段(校驗,準備,解析)完成。首先是校驗,此階段主要校驗class文件包含的信息是否符合jvm的規範。具體的校驗通過對文件格式,元數據,字節碼,符號引用驗證來完成。然後是準備,此階段為類變量分配內存,並將其初始化為默認值。最後是解析,即把類型中的符號引用轉換成為直接引用。具體的解析有4種,1.類或接口的解析,2.欄位解析,3.類方法解析,4.接口方法解析。完成這3個階段就完成了類的連接。
初始化:即執行類的構造器方法的過程。有5種方法可以完成初始化:1.調用new方法,2.使用Class類的newInstance方法(反射機制),3.使用Constructor類的newInstance方法(反射機制),4.使用Clone方法創建對象,5.使用(反)序列化機制創建對象
使用:完成類的初始化後,就可以對類進行實例化,在程序中進行使用了
卸載:當類被加載,連接和初始化後,它的生命周期就始了,當代表類的class對象不在被引用時,class對象就會結束生命周期,類在方法區內的數據就會被卸載。因此一個類何時結束生命,取決於代表它的class對象何時結束生命。
二、JVM的內存結構
Java中的內存分配:
Java程序在運行時,需要在內存中的分配空間。為了提高運算效率,就對數據進行了不同空間的劃分,因為每一片區域都有特定的處理數據方式和內存管理方式。
具體劃分為如下5個內存空間:(非常重要)
棧:存放局部變量
堆:存放所有new出來的東西
方法區:被虛擬機加載的類信息、常量、靜態常量等。
程序計數器(和系統相關)
本地方法棧
通常在面試中會圍繞這5個空間展開
三、GC算法及垃圾回收器
常見的垃圾回收算法:標記-清除,複製,標記-壓縮,分代收集
常用的垃圾回收集器:Serial收集器,ParNew收集器,Paralle收集器,Paralle Old收集器,Cms收集器,G1收集器
在實際應用中,我們可以根據不同的應用需求及伺服器的配置來配置相應的垃圾回收器。
四、JVM調優
jvm調優沒有一個固定模板配置說必須如何操作,它需要根據系統的情況不同對待。
但是可以有如下建議:
1、初始化內存和最大內存儘量保持一致,避免內存不夠用繼續擴充內存。最大內存不要超過物理內存,例如內存8g,你可以設置最大內存4g/6g但是不能超過8g否則加載類的時候沒有空間會報錯。
2、gc/full gc頻率不要太高、每次gc時間不要太長、根據系統應用來定。
常用調優工具:
jps:查看所有的jvm進程,包括進程ID,進程啟動的路徑等等。
jstack:觀察jvm中當前所有線程的運行情況和線程當前狀態。
jstat:利用JVM內建的指令對Java應用程式的資源和性能進行實時的命令行的監控,包括了對進程的classloader,compiler,gc情況;
jmap:監視進程運行中的jvm物理內存的佔用情況,該進程內存內,所有對象的情況,例如產生了哪些對象,對象數量;
jinfo:觀察進程運行環境參數,包括Java System屬性和JVM命令行參數。
五:JVM常會問的面試題
jvm的初始化步驟?類的加載過程jvm的內存結構?每塊內存分別存的什麼信息雙親委派模型GC算法,如何調優FULL GC的條件