更新時間:2023-01-10 14:45:40 來源:動力節點 瀏覽1346次
說道jvm調優必定是我們在面試程序員的時候被問到的問題,畢竟我們在工作中常會用到Java虛擬機,所以,面試Java相關崗位的時候Jvm幾乎是必問的,所以,這幾點到jvm調優面試題希望可以幫助到大家:
1、說一下JVM的主要組成部分?及其作用?
class loader 類加載器:加載類文件到內存。Class loader只管加載,只要符合文件結構就加載,至于能否運行,它不負責,那是有Exectution Engine負責的。
exection engine :執行引擎也叫解釋器,負責解釋命令,交由操作系統執行。
native interface:本地接口。本地接口的作用是融合不同的語言為java所用。
Runtimedata area 運行數據區:運行數據區是jvm的重點,我們所有所寫的程序都被加載到這里,之后才開始運行。
stack:棧也叫棧內存,是java程序的運行區,是在線程創建時創建,它的生命周期跟隨線程的生命周期,線程結束棧內存釋放;對于棧來說不存在垃圾回收的問題,只要線程一結束,該棧就結束。棧中的數據以棧幀的格式存在,棧幀是一個內存區塊,是一個數據集,是一個有關方法和運行期數據的集合,當一個方法A被調用時就產生了一個棧幀F1,并被壓入到棧中,A方法又調用了B方法,于是產生棧幀F2也被壓入棧,執行完畢后,先彈出F2棧幀,再彈出F1棧幀,遵循“先進后出”原則。
堆內存:一個JVM實例只存在一個堆內存,堆內存的大小是可以調節的。類的加載器讀取了類文件之后,需要把類、方法、常變量放到堆內存中,以方便執行器執行,堆內存分三部分:永久存儲(用于存放jdk自身攜帶的class,interface的元數據,也就是說它存儲的是運行環境必須的類信息,被裝載至此區域的數據是不會被垃圾回收掉的,只有關閉jvm釋放此區域所占用的內存)區、新生區、老年代
method area方法區:方法去是被所有線程共享,該區域保存的所有字段和字節方法碼以及一些特殊方法如構造函數,接口代碼也在此定義。
PC Register 程序計數器:每個線程都有一個程序計數器,就是一個指針,指向方法區中的方法字節碼,由執行引擎讀取下一條指令
2、說一下JVM運行時數據區?
不同虛擬機的運行時數據區可能略微有所不同,但都會遵從 Java 虛擬機規范, Java 虛擬機規范規定的區域分為以下 5 個部分:
程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工作是通過改變這個計數器的值,來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都需要依賴這個計數器來完成;
Java 虛擬機棧(Java Virtual Machine Stacks):用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息;
本地方法棧(Native Method Stack):與虛擬機棧的作用是一樣的,只不過虛擬機棧是服務 Java 方法的,而本地方法棧是為虛擬機調用 Native 方法服務的;
Java 堆(Java Heap):Java 虛擬機中內存最大的一塊,是被所有線程共享的,幾乎所有的對象實例都在這里分配內存;
方法區(Methed Area):用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯后的代碼等數據。
3、隊列和棧是什么?有什么區別?
隊列和棧都是被用來預存儲數據的。隊列允許先進先出檢索元素,但也有例外的情況,Deque 接口允許從兩端檢索元素。棧和隊列很相似,但它運行對元素進行后進先出進行檢索。
4、什么是雙親委派模型?
在介紹雙親委派模型之前先說下類加載器。對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立在 JVM 中的唯一性,每一個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將 class 文件加載到 JVM 內存,然后再轉化為 class 對象。
類加載器分類:
啟動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分,用來加載Java_HOME/lib/目錄中的,或者被 -Xbootclasspath 參數所指定的路徑中并且被虛擬機識別的類庫;其他類加載器:擴展類加載器(Extension ClassLoader):負責加載\lib\ext目錄或Java. ext. dirs系統變量指定的路徑中的所有類庫;應用程序類加載器(Application ClassLoader)。負責加載用戶類路徑(classpath)上的指定類庫,我們可以直接使用這個類加載器。一般情況,如果我們沒有自定義類加載器默認就是用這個加載器。雙親委派模型:如果一個類加載器收到了類加載的請求,它首先不會自己去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣所有的加載請求都會被傳送到頂層的啟動類加載器中,只有當父加載無法完成加載請求(它的搜索范圍中沒找到所需的類)時,子加載器才會嘗試去加載類。
5、說一下類裝載的執行過程?
類裝載分為以下 5 個步驟:
加載:根據查找路徑找到相應的 class 文件然后導入;檢查:檢查加載的 class 文件的正確性;準備:給類中的靜態變量分配內存空間;解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解為一個標示,而在直接引用直接指向內存中的地址;初始化:對靜態變量和靜態代碼塊執行初始化工作。
6、怎么判斷對象是否可以被回收?
一般有兩種方法來判斷:
引用計數器:為每個對象創建一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器為 0 時就可以被回收。它有一個缺點不能解決循環引用的問題;可達性分析:從 GC Roots 開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證明此對象是可以被回收的。
7、Java中都有哪些引用類型?
強引用:發生 gc 的時候不會被回收。軟引用:有用但不是必須的對象,在發生內存溢出之前會被回收。弱引用:有用但不是必須的對象,在下一次GC時會被回收。虛引用(幽靈引用/幻影引用):無法通過虛引用獲得對象,用 PhantomReference 實現虛引用,虛引用的用途是在 gc 時返回一個通知。
8、說一下JVM有哪些垃圾回收算法?
標記-清除算法:標記無用對象,然后進行清除回收。缺點:效率不高,無法清除垃圾碎片。標記-整理算法:標記無用對象,讓所有存活的對象都向一端移動,然后直接清除掉端邊界以外的內存。復制算法:按照容量劃分二個大小相等的內存區域,當一塊用完的時候將活著的對象復制到另一塊上,然后再把已使用的內存空間一次清理掉。缺點:內存使用率不高,只有原來的一半。分代算法:根據對象存活周期的不同將內存劃分為幾塊,一般是新生代和老年代,新生代基本采用復制算法,老年代采用標記整理算法。
9、說一下JVM有哪些垃圾回收器?
Serial:最早的單線程串行垃圾回收器。
Serial Old:Serial 垃圾回收器的老年版本,同樣也是單線程的,可以作為 CMS 垃圾回收器的備選預案。
ParNew:是 Serial 的多線程版本。
Parallel 和 ParNew 收集器類似是多線程的,但 Parallel 是吞吐量優先的收集器,可以犧牲等待時間換取系統的吞吐量。
Parallel Old 是 Parallel 老生代版本,Parallel 使用的是復制的內存回收算法,
Parallel Old 使用的是標記-整理的內存回收算法。
CMS:一種以獲得最短停頓時間為目標的收集器,非常適用 B/S 系統。
G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 以后的默認 GC 選項。
以上就是“需要被我們記住的jvm調優面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習