溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java程序員面試BAT大廠,逃脫不了JVM,7月最新20道JVM面試題

發(fā)布時(shí)間:2020-06-13 19:00:00 來(lái)源:網(wǎng)絡(luò) 閱讀:279 作者:架構(gòu)師追風(fēng) 欄目:編程語(yǔ)言

很多人說(shuō)JVM是不是真的要學(xué)?面試官都會(huì)問(wèn)JVM的問(wèn)題嗎?很重要嗎?
的確很重要。
隨著互聯(lián)網(wǎng)的發(fā)展,高并發(fā)高可用、快速響應(yīng)成為軟件的必須,而JVM與這些有著密切關(guān)聯(lián)。
我們?cè)诒M情享受Java虛擬機(jī)帶來(lái)好處的同時(shí),還應(yīng)該去了解和思考“這些技術(shù)特性是如何實(shí)現(xiàn)的”,去了解最底層的原理。只有熟悉JVM,你才能在遇到OutOfMemory等異常時(shí),不會(huì)束手無(wú)策,不會(huì)一臉懵逼的上網(wǎng)找解決辦法,最后就算改了幾個(gè)啟動(dòng)參數(shù)解決了問(wèn)題,也還是云里霧里。
其實(shí),“為什么學(xué)Java虛擬機(jī)”這個(gè)問(wèn)題,就和“為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法”是一個(gè)道理:工欲善其事,必先利其器??梢哉f(shuō),Java虛擬機(jī)就是每一位Java工程師進(jìn)階加薪的利器,你想往上升,你想深入技術(shù),不想一直停留在簡(jiǎn)單開(kāi)發(fā),或者你在做Java性能分析、調(diào)優(yōu)工作時(shí),那么,Java虛擬機(jī)絕對(duì)是一把助力的利劍。
Java程序員面試BAT大廠,逃脫不了JVM,7月最新20道JVM面試題

1.內(nèi)存模型以及分區(qū),需要詳細(xì)到每個(gè)區(qū)放什么。
JVM 分為堆區(qū)和棧區(qū),還有方法區(qū),初始化的對(duì)象放在堆里面,引用放在棧里面,class類信息常量池(static常量和static變量)等放在方法區(qū)
new:
方法區(qū):主要是存儲(chǔ)類信息,常量池(static常量和static變量),編譯后的代碼(字節(jié)碼)等數(shù)據(jù)

堆:初始化的對(duì)象,成員變量 (那種非static的變量),所有的對(duì)象實(shí)例和數(shù)組都要在堆上分配

棧:棧的結(jié)構(gòu)是棧幀組成的,調(diào)用一個(gè)方法就壓入一幀,幀上面存儲(chǔ)局部變量表,操作數(shù)棧,方法出口等信息,局部變量表存放的是8大基礎(chǔ)類型加上一個(gè)應(yīng)用類型,所以還是一個(gè)指向地址的指針

本地方法棧:主要為Native方法服務(wù)

程序計(jì)數(shù)器:記錄當(dāng)前線程執(zhí)行的行號(hào)

2.堆里面的分區(qū):Eden,survival (from+ to),老年代,各自的特點(diǎn)。
堆里面分為新生代和老生代(java8取消了永久代,采用了Metaspace),新生代包含Eden+Survivor區(qū),survivor區(qū)里面分為from和to區(qū),內(nèi)存回收時(shí),如果用的是復(fù)制算法,從from復(fù)制到to,當(dāng)經(jīng)過(guò)一次或者多次GC之后,存活下來(lái)的對(duì)象會(huì)被移動(dòng)到老年區(qū),當(dāng)JVM內(nèi)存不夠用的時(shí)候,會(huì)觸發(fā)Full GC,清理JVM老年區(qū)

當(dāng)新生區(qū)滿了之后會(huì)觸發(fā)YGC,先把存活的對(duì)象放到其中一個(gè)Survice 區(qū),然后進(jìn)行垃圾清理。因?yàn)槿绻麅H僅清理需要?jiǎng)h除的對(duì)象,這樣會(huì)導(dǎo)致內(nèi)存碎 片,因此一般會(huì)把Eden 進(jìn)行完全的清理,然后整理內(nèi)存。那么下次GC 的時(shí)候, 就會(huì)使用下一個(gè)Survive,這樣循環(huán)使用。如果有特別大的對(duì)象,新生代放不下, 就會(huì)使用老年代的擔(dān)保,直接放到老年代里面。因?yàn)镴VM 認(rèn)為,一般大對(duì)象的存 活時(shí)間一般比較久遠(yuǎn)。
Java程序員面試BAT大廠,逃脫不了JVM,7月最新20道JVM面試題

3.對(duì)象創(chuàng)建方法,對(duì)象的內(nèi)存分配,對(duì)象的訪問(wèn)定位。
new 一個(gè)對(duì)象

4.GC的兩種判定方法:
引用計(jì)數(shù)法:指的是如果某個(gè)地方引用了這個(gè)對(duì)象就+1,如果失效了就-1,當(dāng)為0就會(huì)回收但是JVM沒(méi)有用這種方式,因?yàn)闊o(wú)法判定相互循環(huán)引用(A引用B,B引用A)的情況

引用鏈法: 通過(guò)一種GC ROOT的對(duì)象(方法區(qū)中靜態(tài)變量引用的對(duì)象等-static變量)來(lái)判斷,如果有一條鏈能夠到達(dá)GC ROOT就說(shuō)明,不能到達(dá)GC ROOT就說(shuō)明可以回收

5.SafePoint是什么

比如GC的時(shí)候必須要等到Java線程都進(jìn)入到safepoint的時(shí)候VMThread才能開(kāi)始執(zhí)行GC,
循環(huán)的末尾 (防止大循環(huán)的時(shí)候一直不進(jìn)入safepoint,而其他線程在等待它進(jìn)入safepoint)

方法返回前

調(diào)用方法的call之后

拋出異常的位置
Java程序員面試BAT大廠,逃脫不了JVM,7月最新20道JVM面試題

6.GC的三種收集方法:標(biāo)記清除、標(biāo)記整理、復(fù)制算法的原理與特點(diǎn),分別用在什么地方,如果讓你優(yōu)化收集方法,有什么思路?
先標(biāo)記,標(biāo)記完畢之后再清除,效率不高,會(huì)產(chǎn)生碎片

復(fù)制算法:分為8:1的Eden區(qū)和survivor區(qū),就是上面談到的YGC

標(biāo)記整理:標(biāo)記完畢之后,讓所有存活的對(duì)象向一端移動(dòng)

7.GC收集器有哪些?CMS收集器與G1收集器的特點(diǎn)。
并行收集器:串行收集器使用一個(gè)單獨(dú)的線程進(jìn)行收集,GC時(shí)服務(wù)有停頓時(shí)間

串行收集器:次要回收中使用多線程來(lái)執(zhí)行

CMS收集器是基于“標(biāo)記—清除”算法實(shí)現(xiàn)的,經(jīng)過(guò)多次標(biāo)記才會(huì)被清除

G1從整體來(lái)看是基于“標(biāo)記—整理”算法實(shí)現(xiàn)的收集器,從局部(兩個(gè)Region之間)上來(lái)看是基于“復(fù)制”算法實(shí)現(xiàn)的

8.Minor GC與Full GC分別在什么時(shí)候發(fā)生?
新生代內(nèi)存不夠用時(shí)候發(fā)生MGC也叫YGC,JVM內(nèi)存不夠的時(shí)候發(fā)生FGC

9.幾種常用的內(nèi)存調(diào)試工具:jmap、jstack、jconsole、jhat

jstack 可以看當(dāng)前棧的情況,jmap 查看內(nèi)存,jhat 進(jìn)行 dump 堆的信息

mat(eclipse 的也要了解一下)

10.類加載的幾個(gè)過(guò)程
加載、驗(yàn)證、準(zhǔn)備、解析、初始化。然后是使用和卸載了
通過(guò)全限定名來(lái)加載生成 class 對(duì)象到內(nèi)存中,然后進(jìn)行驗(yàn)證這個(gè) class 文件,包括文
件格式校驗(yàn)、元數(shù)據(jù)驗(yàn)證,字節(jié)碼校驗(yàn)等。準(zhǔn)備是對(duì)這個(gè)對(duì)象分配內(nèi)存。解析是將符
號(hào)引用轉(zhuǎn)化為直接引用(指針引用),初始化就是開(kāi)始執(zhí)行構(gòu)造器的代碼

11.JVM內(nèi)存分哪幾個(gè)區(qū),每個(gè)區(qū)的作用是什么?
java 虛擬機(jī)主要分為以下一個(gè)區(qū):
方法區(qū):

  1. 有時(shí)候也成為永久代,在該區(qū)內(nèi)很少發(fā)生垃圾回收,但是并不代表不發(fā)生 GC,在這里
    進(jìn)行的 GC 主要是對(duì)方法區(qū)里的常量池和對(duì)類型的卸載
  2. 方法區(qū)主要用來(lái)存儲(chǔ)已被虛擬機(jī)加載的類的信息、常量、靜態(tài)變量和即時(shí)編譯器編譯后
    的代碼等數(shù)據(jù)。
  3. 該區(qū)域是被線程共享的。
  4. 方法區(qū)里有一個(gè)運(yùn)行時(shí)常量池,用于存放靜態(tài)編譯產(chǎn)生的字面量和符號(hào)引用。該常量池
    具有動(dòng)態(tài)性,也就是說(shuō)常量并不一定是編譯時(shí)確定,運(yùn)行時(shí)生成的常量也會(huì)存在這個(gè)常量
    池中。
    虛擬機(jī)棧:
  5. 虛擬機(jī)棧也就是我們平常所稱的棧內(nèi)存,它為 java 方法服務(wù),每個(gè)方法在執(zhí)行的時(shí)候都
    會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接和方法出口等信息。
  6. 虛擬機(jī)棧是線程私有的,它的生命周期與線程相同。
  7. 局部變量表里存儲(chǔ)的是基本數(shù)據(jù)類型、returnAddress 類型(指向一條字節(jié)碼指令的地
    址)和對(duì)象引用,這個(gè)對(duì)象引用有可能是指向?qū)ο笃鹗嫉刂返囊粋€(gè)指針,也有可能是代表
    對(duì)象的句柄或者與對(duì)象相關(guān)聯(lián)的位置。局部變量所需的內(nèi)存空間在編譯器間確定
    4.操作數(shù)棧的作用主要用來(lái)存儲(chǔ)運(yùn)算結(jié)果以及運(yùn)算的操作數(shù),它不同于局部變量表通過(guò)索
    引來(lái)訪問(wèn),而是壓棧和出棧的方式
    5.每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用,持有這個(gè)引用是為了
    支持方法調(diào)用過(guò)程中的動(dòng)態(tài)連接.動(dòng)態(tài)鏈接就是將常量池中的符號(hào)引用在運(yùn)行期轉(zhuǎn)化為直接
    引用。
    本地方法棧
    本地方法棧和虛擬機(jī)棧類似,只不過(guò)本地方法棧為 Native 方法服務(wù)。

    java 堆是所有線程所共享的一塊內(nèi)存,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,幾乎所有的對(duì)象實(shí)例都在這
    里創(chuàng)建,因此該區(qū)域經(jīng)常發(fā)生垃圾回收操作。
    程序計(jì)數(shù)器
    內(nèi)存空間小,字節(jié)碼解釋器工作時(shí)通過(guò)改變這個(gè)計(jì)數(shù)值可以選取下一條需要執(zhí)行的字節(jié)碼
    指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理和線程恢復(fù)等功能都需要依賴這個(gè)計(jì)數(shù)器完成。該內(nèi)
    存區(qū)域是唯一一個(gè) java 虛擬機(jī)規(guī)范沒(méi)有規(guī)定任何 OOM 情況的區(qū)域。

12.如和判斷一個(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)槿绻?finalize()執(zhí)行緩慢或者發(fā)生了死鎖,那么就會(huì)造成 F-
Queue 隊(duì)列一直等待,造成了內(nèi)存回收系統(tǒng)的崩潰。GC 對(duì)處于 F-Queue 中的對(duì)象進(jìn)行
第二次被標(biāo)記,這時(shí),該對(duì)象將被移除”即將回收”集合,等待回收。

13.簡(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)行回收。

14.java中垃圾收集的方法有哪些?

  1. 標(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)作。
  2. 復(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 堆又分為新生代和老年代)
  3. 標(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)存碎片了。
  4. 分代收集
    現(xiàn)在的虛擬機(jī)垃圾收集大多采用這種方式,它根據(jù)對(duì)象的生存周期,將堆分為新生
    代和老年代。在新生代中,由于對(duì)象生存期短,每次回收都會(huì)有大量對(duì)象死去,那
    么這時(shí)就采用復(fù)制算法。老年代里的對(duì)象存活率較高,沒(méi)有額外的空間進(jìn)行分配擔(dān)
    保,所以可以使用標(biāo)記-整理 或者 標(biāo)記-清除。

15.java內(nèi)存模型
java 內(nèi)存模型(JMM)是線程間通信的控制機(jī)制.JMM 定義了主內(nèi)存和線程之間抽象關(guān)系。
線程之間的共享變量存儲(chǔ)在主內(nèi)存(main memory)中,每個(gè)線程都有一個(gè)私有的本地
內(nèi)存(local memory),本地內(nèi)存中存儲(chǔ)了該線程以讀/寫共享變量的副本。本地內(nèi)存是
JMM 的一個(gè)抽象概念,并不真實(shí)存在。它涵蓋了緩存,寫緩沖區(qū),寄存器以及其他的硬
件和編譯器優(yōu)化。Java 內(nèi)存模型的抽象示意圖如下:
從上圖來(lái)看,線程 A 與線程 B 之間如要通信的話,必須要經(jīng)歷下面 2 個(gè)步驟:

  1. 首先,線程 A 把本地內(nèi)存 A 中更新過(guò)的共享變量刷新到主內(nèi)存中去。
  2. 然后,線程 B 到主內(nèi)存中去讀取線程 A 之前已更新過(guò)的共享變量。

16.java類加載過(guò)程?
java 類加載需要經(jīng)歷一下 7 個(gè)過(guò)程:
加載
加載時(shí)類加載的第一個(gè)過(guò)程,在這個(gè)階段,將完成一下三件事情:

  1. 通過(guò)一個(gè)類的全限定名獲取該類的二進(jìn)制流。
  2. 將該二進(jìn)制流中的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法去運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。
  3. 在內(nèi)存中生成該類的 Class 對(duì)象,作為該類的數(shù)據(jù)訪問(wèn)入口。
    驗(yàn)證
    驗(yàn)證的目的是為了確保 Class 文件的字節(jié)流中的信息不回危害到虛擬機(jī).在該階段主要完成
    以下四鐘驗(yàn)證:
  4. 文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合 Class 文件的規(guī)范,如主次版本號(hào)是否在當(dāng)前虛擬
    機(jī)范圍內(nèi),常量池中的常量是否有不被支持的類型.
  5. 元數(shù)據(jù)驗(yàn)證:對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義分析,如這個(gè)類是否有父類,是否集成了不
    被繼承的類等。
  6. 字節(jié)碼驗(yàn)證:是整個(gè)驗(yàn)證過(guò)程中最復(fù)雜的一個(gè)階段,通過(guò)驗(yàn)證數(shù)據(jù)流和控制流的分析,
    確定程序語(yǔ)義是否正確,主要針對(duì)方法體的驗(yàn)證。如:方法中的類型轉(zhuǎn)換是否正確,跳轉(zhuǎn)
    指令是否正確等。
  7. 符號(hào)引用驗(yàn)證:這個(gè)動(dòng)作在后面的解析過(guò)程中發(fā)生,主要是為了確保解析動(dòng)作能正確執(zhí)
    行。
    準(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ì)變
    為 123 。

解析
該階段主要完成符號(hào)引用到直接引用的轉(zhuǎn)換動(dòng)作。解析動(dòng)作并不一定在初始化動(dòng)作完成之
前,也有可能在初始化之后。
初始化
初始化時(shí)類加載的最后一步,前面的類加載過(guò)程,除了在加載階段用戶應(yīng)用程序可以通過(guò)
自定義類加載器參與之外,其余動(dòng)作完全由虛擬機(jī)主導(dǎo)和控制。到了初始化階段,才真正
開(kāi)始執(zhí)行類中定義的 Java 程序代碼。

17. 簡(jiǎn)述java類加載機(jī)制?
虛擬機(jī)把描述類的數(shù)據(jù)從 Class 文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),解析和初始化,最
終形成可以被虛擬機(jī)直接使用的 java 類型。

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

19.什么是類加載器,類加載器有哪些?
實(shí)現(xiàn)通過(guò)類的權(quán)限定名獲取該類的二進(jìn)制字節(jié)流的代碼塊叫做類加載器。
主要有一下四種類加載器:

  1. 啟動(dòng)類加載器(Bootstrap ClassLoader)用來(lái)加載 java 核心類庫(kù),無(wú)法被 java 程序直接
    引用。
  2. 擴(kuò)展類加載器(extensions class loader):它用來(lái)加載 Java 的擴(kuò)展庫(kù)。Java 虛擬機(jī)的
    實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類。
  3. 系統(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)獲取它。
  4. 用戶自定義類加載器,通過(guò)繼承 java.lang.ClassLoader 類的方式實(shí)現(xiàn)。

20.簡(jiǎn)述java內(nèi)存分配與回收策率以及Minor GC和Major GC

  1. 對(duì)象優(yōu)先在堆的 Eden 區(qū)分配。
  2. 大對(duì)象直接進(jìn)入老年代.
  3. 長(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 這樣可以加快老年代的回收速度。
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI