欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

2019年JVM面試都問(wèn)了什么?(附答案解析)

  發(fā)布時(shí)間:2019-12-04 16:05:07   作者:程序員追風(fēng)   我要評(píng)論
這篇文章主要介紹了2019年JVM面試都問(wèn)了什么?(附答案解析),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

一. Java 類加載過(guò)程?

Java 類加載需要經(jīng)歷一下 7 個(gè)過(guò)程:

1. 加載

加載是類加載的第一個(gè)過(guò)程,在這個(gè)階段,將完成一下三件事情:

• 通過(guò)一個(gè)類的全限定名獲取該類的二進(jìn)制流。

• 將該二進(jìn)制流中的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法去運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。

• 在內(nèi)存中生成該類的 Class 對(duì)象,作為該類的數(shù)據(jù)訪問(wèn)入口。

2. 驗(yàn)證

驗(yàn)證的目的是為了確保 Class 文件的字節(jié)流中的信息不回危害到虛擬機(jī).在該階段主要完成以下四鐘驗(yàn)證:

• 文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合 Class 文件的規(guī)范,如主次版本號(hào)是否在當(dāng)前虛擬機(jī)范圍內(nèi),常量池中的常量是否有不被支持的類型.

• 元數(shù)據(jù)驗(yàn)證:對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義分析,如這個(gè)類是否有父類,是否集成了不被繼承的類等。

• 字節(jié)碼驗(yàn)證:是整個(gè)驗(yàn)證過(guò)程中最復(fù)雜的一個(gè)階段,通過(guò)驗(yàn)證數(shù)據(jù)流和控制流的分析,確定程序語(yǔ)義是否正確,主要針對(duì)方法體的驗(yàn)證。如:方法中的類型轉(zhuǎn)換是否正確,跳轉(zhuǎn)指令是否正確等。

• 符號(hào)引用驗(yàn)證:這個(gè)動(dòng)作在后面的解析過(guò)程中發(fā)生,主要是為了確保解析動(dòng)作能正確執(zhí)行。

3. 準(zhǔn)備

準(zhǔn)備階段是為類的靜態(tài)變量分配內(nèi)存并將其初始化為默認(rèn)值,這些內(nèi)存都將在方法區(qū)中進(jìn)行分配。準(zhǔn)備階段不分配類中的實(shí)例變量的內(nèi)存,實(shí)例變量將會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一起分配在 Java 堆中。

public static int value=123;//在準(zhǔn)備階段 value 初始值為 0 。在初始化階段才會(huì)變?yōu)?123

4. 解析

該階段主要完成符號(hào)引用到直接引用的轉(zhuǎn)換動(dòng)作。解析動(dòng)作并不一定在初始化動(dòng)作完成之前,也有可能在初始化之后。

5. 初始化

初始化時(shí)類加載的最后一步,前面的類加載過(guò)程,除了在加載階段用戶應(yīng)用程序可以通過(guò)自定義類加載器參與之外,其余動(dòng)作完全由虛擬機(jī)主導(dǎo)和控制。到了初始化階段,才真正開(kāi)始執(zhí)行類中定義的Java 程序代碼。

6. 使用

7. 卸載

二.描述一下 JVM 加載 Class 文件的原理機(jī)制?

Java 語(yǔ)言是一種具有動(dòng)態(tài)性的解釋型語(yǔ)言,類(Class)只有被加載到 JVM 后才能運(yùn)行。當(dāng)運(yùn)行指定程序時(shí),JVM 會(huì)將編譯生成的 .class 文件按照需求和一定的規(guī)則加載到內(nèi)存中,并組織成為一個(gè)完整的 Java 應(yīng)用程序。這個(gè)加載過(guò)程是由類加載器完成,具體來(lái)說(shuō),就是由 ClassLoader 和它的子類來(lái)實(shí)現(xiàn)的。類加載器本身也是一個(gè)類,其實(shí)質(zhì)是把類文件從硬盤讀取到內(nèi)存中。

類的加載方式分為隱式加載和顯示加載。隱式加載指的是程序在使用 new 等方式創(chuàng)建對(duì)象時(shí),會(huì)隱式地調(diào)用類的加載器把對(duì)應(yīng)的類加載到 JVM 中。顯示加載指的是通過(guò)直接調(diào)用 class.forName()方法來(lái)把所需的類加載到 JVM 中。

任何一個(gè)工程項(xiàng)目都是由許多類組成的,當(dāng)程序啟動(dòng)時(shí),只把需要的類加載到 JVM 中,其他類只有被使用到的時(shí)候才會(huì)被加載,采用這種方法一方面可以加快加載速度,另一方面可以節(jié)約程序運(yùn)行時(shí)對(duì)內(nèi)存的開(kāi)銷。此外,在 Java 語(yǔ)言中,每個(gè)類或接口都對(duì)應(yīng)一個(gè) .class 文件,這些文件可以被看成是一個(gè)個(gè)可以被動(dòng)態(tài)加載的單元,因此當(dāng)只有部分類被修改時(shí),只需要重新編譯變化的類即可,而不需要重新編譯所有文件,因此加快了編譯速度。

在 Java 語(yǔ)言中,類的加載是動(dòng)態(tài)的,它并不會(huì)一次性將所有類全部加載后再運(yùn)行,而是保證程序運(yùn)行的基礎(chǔ)類(例如基類)完全加載到 JVM 中,至于其他類,則在需要的時(shí)候才加載。

類加載的主要步驟:

• 裝載,根據(jù)查找路徑找到相應(yīng)的 class 文件,然后導(dǎo)入。

• 鏈接,鏈接又可分為 3 個(gè)小步:

• 檢查,檢查待加載的 class 文件的正確性。

• 準(zhǔn)備,給類中的靜態(tài)變量分配存儲(chǔ)空間。

• 解析,將符號(hào)引用轉(zhuǎn)換為直接引用(這一步可選)

• 初始化。對(duì)靜態(tài)變量和靜態(tài)代碼塊執(zhí)行初始化工作。

三 Java 內(nèi)存分配。

• 寄存器:我們無(wú)法控制。

• 靜態(tài)域:static 定義的靜態(tài)成員。

• 常量池:編譯時(shí)被確定并保存在 .class 文件中的(final)常量值和一些文本修飾的符號(hào)引用(類和接口的全限定名,字段的名稱和描述符,方法和名稱和描述符)。

• 非 RAM 存儲(chǔ):硬盤等永久存儲(chǔ)空間。

• 堆內(nèi)存:new 創(chuàng)建的對(duì)象和數(shù)組,由 Java 虛擬機(jī)自動(dòng)垃圾回收器管理,存取速度慢。

• 棧內(nèi)存:基本類型的變量和對(duì)象的引用變量(堆內(nèi)存空間的訪問(wèn)地址),速度快,可以共享,但是大小與生存期必須確定,缺乏靈活性。

Java 堆的結(jié)構(gòu)是什么樣子的?什么是堆中的永久代(Perm Genspace)?

JVM 的堆是運(yùn)行時(shí)數(shù)據(jù)區(qū),所有類的實(shí)例和數(shù)組都是在堆上分配內(nèi)存。它在 JVM 啟動(dòng)的時(shí)候被創(chuàng)建。對(duì)象所占的堆內(nèi)存是由自動(dòng)內(nèi)存管理系統(tǒng)也就是垃圾收集器回收。

堆內(nèi)存是由存活和死亡的對(duì)象組成的。存活的對(duì)象是應(yīng)用可以訪問(wèn)的,不會(huì)被垃圾回收。死亡的對(duì)象是應(yīng)用不可訪問(wèn)尚且還沒(méi)有被垃圾收集器回收掉的對(duì)象。一直到垃圾收集器把這些 對(duì)象回收掉之前,他們會(huì)一直占據(jù)堆內(nèi)存空間。

四.GC 是什么? 為什么要有 GC?

GC 是垃圾收集的意思(GabageCollection),內(nèi)存處理是編程人員容易出現(xiàn)問(wèn)題的地方,忘記或者錯(cuò)誤的內(nèi)存回收會(huì)導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java 提供的 GC 功能可以自動(dòng)監(jiān)測(cè)對(duì)象是否超過(guò)作用域從而達(dá)到自動(dòng)回收內(nèi)存的目的,Java 語(yǔ)言沒(méi)有提供釋放已分配內(nèi)存的顯示操作方法。

五. 簡(jiǎn)述 Java 垃圾回收機(jī)制。

在 Java 中,程序員是不需要顯示的去釋放一個(gè)對(duì)象的內(nèi)存的,而是由虛擬機(jī)自行執(zhí)行。在 JVM 中,有一個(gè)垃圾回收線程,它是低優(yōu)先級(jí)的,在正常情況下是不會(huì)執(zhí)行的,只有在虛擬機(jī)空閑或者當(dāng)前堆內(nèi)存不足時(shí),才會(huì)觸發(fā)執(zhí)行,掃面那些沒(méi)有被任何引用的對(duì)象,并將它們添加到要回收的集合中,進(jìn)行回收。

六. 如何判斷一個(gè)對(duì)象是否存活?(或者 GC 對(duì)象的判定方法)

判斷一個(gè)對(duì)象是否存活有兩種方法:

1. 引用計(jì)數(shù)法

所謂引用計(jì)數(shù)法就是給每一個(gè)對(duì)象設(shè)置一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用這個(gè)對(duì)象時(shí),就將計(jì)數(shù)器加一,引用失效時(shí),計(jì)數(shù)器就減一。當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)器為零時(shí),說(shuō)明此對(duì)象沒(méi)有被引用,也就是“死對(duì)象”,將會(huì)被垃圾回收。

引用計(jì)數(shù)法有一個(gè)缺陷就是無(wú)法解決循環(huán)引用問(wèn)題,也就是說(shuō)當(dāng)對(duì)象 A 引用對(duì)象 B,對(duì)象 B 又引用者對(duì)象 A,那么此時(shí) A、B 對(duì)象的引用計(jì)數(shù)器都不為零,也就造成無(wú)法完成垃圾回收,所以主流的虛擬機(jī)都沒(méi)有采用這種算法。

2. 可達(dá)性算法(引用鏈法)

該算法的思想是:從一個(gè)被稱為 GC Roots 的對(duì)象開(kāi)始向下搜索,如果一個(gè)對(duì)象到 GC Roots 沒(méi)有任何引用鏈相連時(shí),則說(shuō)明此對(duì)象不可用。

在 Java 中可以作為 GC Roots 的對(duì)象有以下幾種:

• 虛擬機(jī)棧中引用的對(duì)象

• 方法區(qū)類靜態(tài)屬性引用的對(duì)象

• 方法區(qū)常量池引用的對(duì)象

• 本地方法棧 JNI 引用的對(duì)象

雖然這些算法可以判定一個(gè)對(duì)象是否能被回收,但是當(dāng)滿足上述條件時(shí),一個(gè)對(duì)象比不一定會(huì)被回收。當(dāng)一個(gè)對(duì)象不可達(dá) GC Root時(shí),這個(gè)對(duì)象并不會(huì)立馬被回收,而是出于一個(gè)死緩的階段,若要被真正的回收需要經(jīng)歷兩次標(biāo)記

如果對(duì)象在可達(dá)性分析中沒(méi)有與 GC Root 的引用鏈,那么此時(shí)就會(huì)被第一次標(biāo)記并且進(jìn)行一次篩選,篩選的條件是是否有必要執(zhí)行finalize() 方法。當(dāng)對(duì)象沒(méi)有覆蓋 finalize() 方法或者已被虛擬機(jī)調(diào)用過(guò),那么就認(rèn)為是沒(méi)必要的。 如果該對(duì)象有必要執(zhí)行finalize() 方法,那么這個(gè)對(duì)象將會(huì)放在一個(gè)稱為 F-Queue 的對(duì)隊(duì)列中,虛擬機(jī)會(huì)觸發(fā)一個(gè) Finalize() 線程去執(zhí)行,此線程是低優(yōu)先級(jí)的,并且虛擬機(jī)不會(huì)承諾一直等待它運(yùn)行完,這是因?yàn)槿绻鹒inalize() 執(zhí)行緩慢或者發(fā)生了死鎖,那么就會(huì)造成 F-Queue 對(duì)列一直等待,造成了內(nèi)存回收系統(tǒng)的崩潰。GC 對(duì)處于 F-Queue中的對(duì)象進(jìn)行第二次被標(biāo)記,這時(shí),該對(duì)象將被移除” 即將回收”集合,等待回收。

七. 垃圾回收的優(yōu)點(diǎn)和原理。并考慮 2 種回收機(jī)制。

Java 語(yǔ)言中一個(gè)顯著的特點(diǎn)就是引入了垃圾回收機(jī)制,使 C++程序員最頭疼的內(nèi)存管理的問(wèn)題迎刃而解,它使得 Java 程序員在編寫(xiě)程序的時(shí)候不再需要考慮內(nèi)存管理。由于有個(gè)垃圾回收機(jī)制,Java 中的對(duì)象不再有“作用域”的概念,只有對(duì)象的引用才有"作用域"。垃圾回收可以有效的防止內(nèi)存泄露,有效的使用可以使用的內(nèi)存。垃圾回收器通常是作為一個(gè)單獨(dú)的低級(jí)別的線程運(yùn)行,不可預(yù)知的情況下對(duì)內(nèi)存堆中已經(jīng)死亡的或者長(zhǎng)時(shí)間沒(méi)有使用的對(duì)象進(jìn)行清楚和回收,程序員不能實(shí)時(shí)的調(diào)用垃圾回收器對(duì)某個(gè)對(duì)象或所有對(duì)象進(jìn)行垃圾回收。

回收機(jī)制有分代復(fù)制垃圾回收和標(biāo)記垃圾回收,增量垃圾回收。

八. 垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內(nèi)存嗎?有什么辦法主動(dòng)通知虛擬機(jī)進(jìn)行垃圾回收?

對(duì)于 GC 來(lái)說(shuō),當(dāng)程序員創(chuàng)建對(duì)象時(shí),GC 就開(kāi)始監(jiān)控這個(gè)對(duì)象的地址、大小以及使用情況。通常,GC 采用有向圖的方式記錄和管理堆(heap)中的所有對(duì)象。通過(guò)這種方式確定哪些對(duì)象是”可達(dá)的”,哪些對(duì)象是”不可達(dá)的”。當(dāng) GC 確定一些對(duì)象為“不可達(dá)”時(shí),GC 就有責(zé)任回收這些內(nèi)存空間??梢浴3绦騿T可以手動(dòng)執(zhí)行 System.gc(),通知 GC 運(yùn)行,但是 Java 語(yǔ)言規(guī)范并不保證 GC 一定會(huì)執(zhí)行。

九. Java 中會(huì)存在內(nèi)存泄漏嗎,請(qǐng)簡(jiǎn)單描述。

所謂內(nèi)存泄露就是指一個(gè)不再被程序使用的對(duì)象或變量一直被占據(jù)在內(nèi)存中。Java 中有垃圾回收機(jī)制,它可以保證一對(duì)象不再被引用的時(shí)候,即對(duì)象變成了孤兒的時(shí)候,對(duì)象將自動(dòng)被垃圾回收器從內(nèi)存中清除掉。由于 Java 使用有向圖的方式進(jìn)行垃圾回收管理,可以消除引用循環(huán)的問(wèn)題,例如有兩個(gè)對(duì)象,相互引用,只要它們和根進(jìn)程不可達(dá)的,那么 GC 也是可以回收它們的。

Java 中的內(nèi)存泄露的情況:長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄露,盡管短生命周期對(duì)象已經(jīng)不再需要,但是因?yàn)殚L(zhǎng)生命周期對(duì)象持有它的引用而導(dǎo)致不能被回收,這就是 Java 中內(nèi)存泄露的發(fā)生場(chǎng)景,通俗地說(shuō),就是程序員可能創(chuàng)建了一個(gè)對(duì)象,以后一直不再使用這個(gè)對(duì)象,這個(gè)對(duì)象卻一直被引用,即這個(gè)對(duì)象無(wú)用但是卻無(wú)法被垃圾回收器回收的,這就是 java中可能出現(xiàn)內(nèi)存泄露的情況,例如,緩存系統(tǒng),我們加載了一個(gè)對(duì)象放在緩存中 (例如放在一個(gè)全局 map 對(duì)象中),然后一直不再使用它,這個(gè)對(duì)象一直被緩存引用,但卻不再被使用。

檢查 Java 中的內(nèi)存泄露,一定要讓程序?qū)⒏鞣N分支情況都完整執(zhí)行到程序結(jié)束,然后看某個(gè)對(duì)象是否被使用過(guò),如果沒(méi)有,則才能判定這個(gè)對(duì)象屬于內(nèi)存泄露。

如果一個(gè)外部類的實(shí)例對(duì)象的方法返回了一個(gè)內(nèi)部類的實(shí)例對(duì)象,這個(gè)內(nèi)部類對(duì)象被長(zhǎng)期引用了,即使那個(gè)外部類實(shí)例對(duì)象不再被使用,但由于內(nèi)部類持久外部類的實(shí)例對(duì)象,這個(gè)外部類對(duì)象將不會(huì)被垃圾回收,這也會(huì)造成內(nèi)存泄露。

內(nèi)存泄露的另外一種情況:當(dāng)一個(gè)對(duì)象被存儲(chǔ)進(jìn) HashSet 集合中以后,就不能修改這個(gè)對(duì)象中的那些參與計(jì)算哈希值的字段了,否則,對(duì)象修改后的哈希值與最初存儲(chǔ)進(jìn) HashSet 集合中時(shí)的哈希值就不同了,在這種情況下,即使在 contains 方法使用該對(duì)象的當(dāng)前引用作為的參數(shù)去 HashSet 集合中檢索對(duì)象,也將返回找不到對(duì)象的結(jié)果,這也會(huì)導(dǎo)致無(wú)法從 HashSet 集合中單獨(dú)刪除當(dāng)前對(duì)象,造成內(nèi)存泄露。

十. 深拷貝和淺拷貝。

簡(jiǎn)單來(lái)講就是復(fù)制、克隆。

Person p=new Person(“張三”);

淺拷貝就是對(duì)對(duì)象中的數(shù)據(jù)成員進(jìn)行簡(jiǎn)單賦值,如果存在動(dòng)態(tài)成員或者指針就會(huì)報(bào)錯(cuò)。

深拷貝就是對(duì)對(duì)象中存在的動(dòng)態(tài)成員或指針重新開(kāi)辟內(nèi)存空間。

十一. System.gc() 和 Runtime.gc() 會(huì)做什么事情?

這兩個(gè)方法用來(lái)提示 JVM 要進(jìn)行垃圾回收。但是,立即開(kāi)始還是延遲進(jìn)行垃圾回收是取決于 JVM 的。

十二. finalize() 方法什么時(shí)候被調(diào)用?析構(gòu)函數(shù) (finalization) 的目的是什么?

垃圾回收器(garbage colector)決定回收某對(duì)象時(shí),就會(huì)運(yùn)行該對(duì)象的 finalize() 方法 但是在 Java 中很不幸,如果內(nèi)存總是充足的,那么垃圾回收可能永遠(yuǎn)不會(huì)進(jìn)行,也就是說(shuō) filalize() 可能永遠(yuǎn)不被執(zhí)行,顯然指望它做收尾工作是靠不住的。 那么finalize() 究竟是做什么的呢? 它最主要的用途是回收特殊渠道申請(qǐng)的內(nèi)存。Java 程序有垃圾回收器,所以一般情況下內(nèi)存問(wèn)題不用程序員操心。但有一種 JNI(Java Native Interface)調(diào)用non-Java 程序(C 或 C++), finalize() 的工作就是回收這部分的內(nèi)存。

十三. 如果對(duì)象的引用被置為 null,垃圾收集器是否會(huì)立即釋放對(duì)象占用的內(nèi)存?

不會(huì),在下一個(gè)垃圾回收周期中,這個(gè)對(duì)象將是可被回收的。

十四. 什么是分布式垃圾回收(DGC)?它是如何工作的?

DGC 叫做分布式垃圾回收。RMI 使用 DGC 來(lái)做自動(dòng)垃圾回收。因?yàn)?RMI 包含了跨虛擬機(jī)的遠(yuǎn)程對(duì)象的引用,垃圾回收是很困難的。DGC 使用引用計(jì)數(shù)算法來(lái)給遠(yuǎn)程對(duì)象提供自動(dòng)內(nèi)存管理。

十五. 串行(serial)收集器和吞吐量(throughput)收集器的區(qū)別是什么?

吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等規(guī)模和大規(guī)模數(shù)據(jù)的應(yīng)用程序。 而串行收集器對(duì)大多數(shù)的小應(yīng)用(在現(xiàn)代處理器上需要大概 100M 左右的內(nèi)存)就足夠了。

十六. 在 Java 中,對(duì)象什么時(shí)候可以被垃圾回收?

當(dāng)對(duì)象對(duì)當(dāng)前使用這個(gè)對(duì)象的應(yīng)用程序變得不可觸及的時(shí)候,這個(gè)對(duì)象就可以被回收了。

十七. 簡(jiǎn)述 Java 內(nèi)存分配與回收策率以及 Minor GC 和 MajorGC。

• 對(duì)象優(yōu)先在堆的 Eden 區(qū)分配

• 大對(duì)象直接進(jìn)入老年代

• 長(zhǎng)期存活的對(duì)象將直接進(jìn)入老年代

當(dāng) Eden 區(qū)沒(méi)有足夠的空間進(jìn)行分配時(shí),虛擬機(jī)會(huì)執(zhí)行一次Minor GC。Minor GC 通常發(fā)生在新生代的 Eden 區(qū),在這個(gè)區(qū)的對(duì)象生存期短,往往發(fā)生 Gc 的頻率較高,回收速度比較快;

Full GC/Major GC 發(fā)生在老年代,一般情況下,觸發(fā)老年代 GC的時(shí)候不會(huì)觸發(fā) Minor GC,但是通過(guò)配置,可以在 Full GC 之前進(jìn)行一次 Minor GC 這樣可以加快老年代的回收速度。

十八. JVM 的永久代中會(huì)發(fā)生垃圾回收么?

垃圾回收不會(huì)發(fā)生在永久代,如果永久代滿了或者是超過(guò)了臨界值,會(huì)觸發(fā)完全垃圾回收(Full GC)。

注:Java 8 中已經(jīng)移除了永久代,新加了一個(gè)叫做元數(shù)據(jù)區(qū)的native 內(nèi)存區(qū)。

十九. Java 中垃圾收集的方法有哪些?

標(biāo)記 - 清除:

這是垃圾收集算法中最基礎(chǔ)的,根據(jù)名字就可以知道,它的思想就是標(biāo)記哪些要被回收的對(duì)象,然后統(tǒng)一回收。這種方法很簡(jiǎn)單,但是會(huì)有兩個(gè)主要問(wèn)題:

1. 效率不高,標(biāo)記和清除的效率都很低;

2. 會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,導(dǎo)致以后程序在分配較大的對(duì)象時(shí),由于沒(méi)有充足的連續(xù)內(nèi)存而提前觸發(fā)一次 GC 動(dòng)作。

復(fù)制算法:

為了解決效率問(wèn)題,復(fù)制算法將可用內(nèi)存按容量劃分為相等的兩部分,然后每次只使用其中的一塊,當(dāng)一塊內(nèi)存用完時(shí),就將還存活的對(duì)象復(fù)制到第二塊內(nèi)存上,然后一次性清楚完第一塊內(nèi)存,再將第二塊上的對(duì)象復(fù)制到第一塊。但是這種方式,內(nèi)存的代價(jià)太高,每次基本上都要浪費(fèi)一般的內(nèi)存。

于是將該算法進(jìn)行了改進(jìn),內(nèi)存區(qū)域不再是按照 1:1 去劃分,而是將內(nèi)存劃分為 8:1:1 三部分,較大那份內(nèi)存交 Eden 區(qū),其余是兩塊較小的內(nèi)存區(qū)叫 Survior 區(qū)。每次都會(huì)優(yōu)先使用 Eden 區(qū),若 Eden 區(qū)滿,就將對(duì)象復(fù)制到第二塊內(nèi)存區(qū)上,然后清除 Eden區(qū),如果此時(shí)存活的對(duì)象太多,以至于 Survivor 不夠時(shí),會(huì)將這些對(duì)象通過(guò)分配擔(dān)保機(jī)制復(fù)制到老年代中。(java 堆又分為新生代和老年代)

標(biāo)記 - 整理:

該算法主要是為了解決標(biāo)記 - 清除,產(chǎn)生大量?jī)?nèi)存碎片的問(wèn)題;當(dāng)對(duì)象存活率較高時(shí),也解決了復(fù)制算法的效率問(wèn)題。它的不同之處就是在清除對(duì)象的時(shí)候現(xiàn)將可回收對(duì)象移動(dòng)到一端,然后清除掉端邊界以外的對(duì)象,這樣就不會(huì)產(chǎn)生內(nèi)存碎片了。

分代收集:

現(xiàn)在的虛擬機(jī)垃圾收集大多采用這種方式,它根據(jù)對(duì)象的生存周期,將堆分為新生代和老年代。在新生代中,由于對(duì)象生存期短,每次回收都會(huì)有大量對(duì)象死去,那么這時(shí)就采用復(fù)制算法。

老年代里的對(duì)象存活率較高,沒(méi)有額外的空間進(jìn)行分配擔(dān)保。

二十. 什么是類加載器,類加載器有哪些?

實(shí)現(xiàn)通過(guò)類的權(quán)限定名獲取該類的二進(jìn)制字節(jié)流的代碼塊叫做類加載器。

主要有一下四種類加載器:

• 啟動(dòng)類加載器(Bootstrap ClassLoader)用來(lái)加載 Java 核心類庫(kù),無(wú)法被 Java 程序直接引用。

• 擴(kuò)展類加載器(extensions class loader):它用來(lái)加載 Java的擴(kuò)展庫(kù)。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類。

• 系統(tǒng)類加載器(system class loader):它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來(lái)加載 Java 類。一般來(lái)說(shuō),Java應(yīng)用的類都是由它來(lái)完成加載的??梢酝ㄟ^(guò)ClassLoader.getSystemClassLoader() 來(lái)獲取它。

• 用戶自定義類加載器,通過(guò)繼承 java.lang.ClassLoader 類的方式實(shí)現(xiàn)。

二十一. 類加載器雙親委派模型機(jī)制?

當(dāng)一個(gè)類收到了類加載請(qǐng)求時(shí),不會(huì)自己先去加載這個(gè)類,而是將其委派給父類,由父類去加載,如果此時(shí)父類不能加載,反饋給子類,由子類去完成類的加載。

總結(jié)

所有的面試題目都不是一成不變的,特別是像一線大廠,上面的面試真題只是給大家一個(gè)借鑒作用,最主要的是給自己增加知識(shí)的儲(chǔ)備,有備無(wú)患。

相關(guān)文章

  • 10道JVM常見(jiàn)面試題解析(附答案)

    這篇文章主要介紹了10道JVM常見(jiàn)面試題解析(附答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)
    2020-09-04
  • JVM相關(guān)面試題及答案(小結(jié))

    這篇文章主要介紹了JVM相關(guān)面試題及答案(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-02
  • 2020面試阿里字節(jié)跳動(dòng)90%被問(wèn)到的JVM面試題附答案(史上最全)

    這篇文章主要介紹了2020面試阿里字節(jié)跳動(dòng)90%被問(wèn)到的JVM面試題附答案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-15
  • 2020年JVM高頻率面試題整理

    這篇文章主要介紹了2020年JVM高頻率面試題整理,真是小編下了血本給大家整理出來(lái)的,值得大家收藏,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-09
  • JVM面試題小結(jié)(2020最新版)

    這篇文章主要介紹了JVM面試題小結(jié)(2020最新版),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-21
  • Java研發(fā)面試99題(含答案):JVM+Spring+MySQL+線程池+鎖

    這篇文章主要介紹了Java研發(fā)面試99題,主要包括了JVM,Spring,MySQL,線程池,鎖等,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-16
  • 講一講JVM的組成(Java經(jīng)典面試題)

    JVM(Java 虛擬機(jī))算是面試必問(wèn)的問(wèn)題的了,而但凡問(wèn) JVM 一定會(huì)問(wèn)的第一個(gè)問(wèn)題就是:講一講 JVM 的組成?那本文就注重講一下 JVM 的組成,感興趣的可以了解一下
    2019-04-10
  • 30道有趣的JVM面試題(小結(jié))

    這篇文章主要介紹了30道有趣的JVM面試題(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-26

最新評(píng)論