日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
面試重點(diǎn):Java虛擬機(jī)常見(jiàn)問(wèn)題詳解

 

在黎川等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需開(kāi)發(fā)網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),全網(wǎng)整合營(yíng)銷(xiāo)推廣,成都外貿(mào)網(wǎng)站建設(shè),黎川網(wǎng)站建設(shè)費(fèi)用合理。

一、Java引用的四種狀態(tài):

強(qiáng)引用

  用的最廣。我們平時(shí)寫(xiě)代碼時(shí),new一個(gè)Object存放在堆內(nèi)存,然后用一個(gè)引用指向它,這就是強(qiáng)引用。

  如果一個(gè)對(duì)象具有強(qiáng)引用,那垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足的問(wèn)題。

軟引用

  如果一個(gè)對(duì)象只具有軟引用,則內(nèi)存空間足夠時(shí),垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。(備注:如果內(nèi)存不足,隨時(shí)有可能被回收。)

  只要垃圾回收器沒(méi)有回收它,該對(duì)象就可以被程序使用。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。

弱引用

  弱引用與軟引用的區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期。

  每次執(zhí)行GC的時(shí)候,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。

虛引用

  “虛引用”顧名思義,就是形同虛設(shè),與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。

  虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收器回收的活動(dòng)。


二、Java中的內(nèi)存劃分:

Java程序在運(yùn)行時(shí),需要在內(nèi)存中的分配空間。為了提高運(yùn)算效率,就對(duì)數(shù)據(jù)進(jìn)行了不同空間的劃分,因?yàn)槊恳黄瑓^(qū)域都有特定的處理數(shù)據(jù)方式和內(nèi)存管理方式。

1、程序計(jì)數(shù)器:(線程私有)

  • 每個(gè)線程擁有一個(gè)程序計(jì)數(shù)器,在線程創(chuàng)建時(shí)創(chuàng)建,

  • 指向下一條指令的地址

  • 執(zhí)行本地方法時(shí),其值為undefined

2、虛擬機(jī)棧:(線程私有)

每個(gè)方法被調(diào)用的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表、操作棧、動(dòng)態(tài)鏈接、方法出口等信息。局部變量表存放的是:編譯期可知的基本數(shù)據(jù)類(lèi)型、對(duì)象引用類(lèi)型。

每個(gè)方法被調(diào)用直到執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)中從入棧到出棧的過(guò)程。

在Java虛擬機(jī)規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常情況:

 ?。?)如果線程請(qǐng)求的棧深度太深,超出了虛擬機(jī)所允許的深度,就會(huì)出現(xiàn)StackOverFlowError(比如***遞歸。因?yàn)槊恳粚訔颊加靡欢臻g,而 Xss 規(guī)定了棧的***空間,超出這個(gè)值就會(huì)報(bào)錯(cuò))

 ?。?)虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展,如果擴(kuò)展到無(wú)法申請(qǐng)足夠的內(nèi)存空間,會(huì)出現(xiàn)OOM

3、本地方法棧:

(1)本地方法棧與java虛擬機(jī)棧作用非常類(lèi)似,其區(qū)別是:java虛擬機(jī)棧是為虛擬機(jī)執(zhí)行java方法服務(wù)的,而本地方法棧則為虛擬機(jī)執(zhí)使用到的Native方法服務(wù)。

(2)Java虛擬機(jī)沒(méi)有對(duì)本地方法棧的使用和數(shù)據(jù)結(jié)構(gòu)做強(qiáng)制規(guī)定,Sun HotSpot虛擬機(jī)就把java虛擬機(jī)棧和本地方法棧合二為一。

(3)本地方法棧也會(huì)拋出StackOverFlowError和OutOfMemoryError。

4、堆:即堆內(nèi)存(線程共享)

(1)堆是java虛擬機(jī)所管理的內(nèi)存區(qū)域中***的一塊,java堆是被所有線程共享的內(nèi)存區(qū)域,在java虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,堆內(nèi)存的唯一目的就是存放對(duì)象實(shí)例幾乎所有的對(duì)象實(shí)例都在堆內(nèi)存分配。

(2)堆是GC管理的主要區(qū)域,從垃圾回收的角度看,由于現(xiàn)在的垃圾收集器都是采用的分代收集算法,因此java堆還可以初步細(xì)分為新生代和老年代。

(3)Java虛擬機(jī)規(guī)定,堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)的即可。在實(shí)現(xiàn)上既可以是固定的,也可以是可動(dòng)態(tài)擴(kuò)展的。如果在堆內(nèi)存沒(méi)有完成實(shí)例分配,并且堆大小也無(wú)法擴(kuò)展,就會(huì)拋出OutOfMemoryError異常。

5、方法區(qū):(線程共享)

(1)用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。

(2)Sun HotSpot虛擬機(jī)把方法區(qū)叫做***代(Permanent Generation),方法區(qū)中最終要的部分是運(yùn)行時(shí)常量池。

三、Java對(duì)象在內(nèi)存中的狀態(tài):

可達(dá)的/可觸及的:

  Java對(duì)象被創(chuàng)建后,如果被一個(gè)或多個(gè)變量引用,那就是可達(dá)的。即從根節(jié)點(diǎn)可以觸及到這個(gè)對(duì)象。

  其實(shí)就是從根節(jié)點(diǎn)掃描,只要這個(gè)對(duì)象在引用鏈中,那就是可觸及的。

可恢復(fù)的:

  Java對(duì)象不再被任何變量引用就進(jìn)入了可恢復(fù)狀態(tài)。

  在回收該對(duì)象之前,該對(duì)象的finalize()方法進(jìn)行資源清理。如果在finalize()方法中重新讓變量引用該對(duì)象,則該對(duì)象再次變?yōu)榭蛇_(dá)狀態(tài),否則該對(duì)象進(jìn)入不可達(dá)狀態(tài)

不可達(dá)的:

  Java對(duì)象不被任何變量引用,且系統(tǒng)在調(diào)用對(duì)象的finalize()方法后依然沒(méi)有使該對(duì)象變成可達(dá)狀態(tài)(該對(duì)象依然沒(méi)有被變量引用),那么該對(duì)象將變成不可達(dá)狀態(tài)。

  當(dāng)Java對(duì)象處于不可達(dá)狀態(tài)時(shí),系統(tǒng)才會(huì)真正回收該對(duì)象所占有的資源。

四、判斷對(duì)象死亡的兩種常用算法:

1、引用計(jì)數(shù)算法:

給對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí),計(jì)數(shù)器值就減1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。

但是,主流的java虛擬機(jī)并沒(méi)有選用引用計(jì)數(shù)算法來(lái)管理內(nèi)存,其中最主要的原因是:它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。

2、根搜索算法:(jvm采用的算法)

設(shè)立若干種根對(duì)象,當(dāng)任何一個(gè)根對(duì)象(GC Root)到某一個(gè)對(duì)象均不可達(dá)時(shí),則認(rèn)為這個(gè)對(duì)象是可以被回收的。

五、垃圾回收算法

1、標(biāo)記-清除算法:

標(biāo)記階段:先通過(guò)根節(jié)點(diǎn),標(biāo)記所有從根節(jié)點(diǎn)開(kāi)始的可達(dá)對(duì)象。因此,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象;

清除階段:清除所有未被標(biāo)記的對(duì)象。

2、復(fù)制算法:(新生代的GC)

  將原有的內(nèi)存空間分為兩塊,每次只使用其中一塊,在垃圾回收時(shí),將正在使用的內(nèi)存中的存活對(duì)象復(fù)制到未使用的內(nèi)存塊中,然后清除正在使用的內(nèi)存塊中的所有對(duì)象。

3、標(biāo)記-整理算法:(老年代的GC)

標(biāo)記階段:先通過(guò)根節(jié)點(diǎn),標(biāo)記所有從根節(jié)點(diǎn)開(kāi)始的可達(dá)對(duì)象。因此,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象

整理階段:將將所有的存活對(duì)象壓縮到內(nèi)存的一端;之后,清理邊界外所有的空間

4、分代收集算法:

存活率低:少量對(duì)象存活,適合復(fù)制算法:在新生代中,每次GC時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,只有少量存活(新生代中98%的對(duì)象都是“朝生夕死”),那就選用復(fù)制算法,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成GC。

存活率高:大量對(duì)象存活,適合用標(biāo)記-清理/標(biāo)記-整理:在老年代中,因?yàn)閷?duì)象存活率高、沒(méi)有額外空間對(duì)他進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記-清理”/“標(biāo)記-整理”算法進(jìn)行GC。

六、垃圾收集器

1、Serial收集器:(串行收集器)

這個(gè)收集器是一個(gè)單線程的收集器,但它的單線程的意義并不僅僅說(shuō)明它只會(huì)使用一個(gè)CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進(jìn)行垃圾收集時(shí),必須暫停其他所有的工作線程(Stop-The-World:將用戶正常工作的線程全部暫停掉),直到它收集結(jié)束。

2、ParNew收集器:Serial收集器的多線程版本(使用多條線程進(jìn)行GC)

  ParNew收集器是Serial收集器的多線程版本。

  它是運(yùn)行在server模式下的***新生代收集器,除了Serial收集器外,目前只有它能與CMS收集器配合工作。CMS收集器是一個(gè)被認(rèn)為具有劃時(shí)代意義的并發(fā)收集器,因此如果有一個(gè)垃圾收集器能和它一起搭配使用讓其更加***,那這個(gè)收集器必然也是一個(gè)不可或缺的部分了。

3、ParNew Scanvenge收集器

  類(lèi)似ParNew,但更加關(guān)注吞吐量。目標(biāo)是:達(dá)到一個(gè)可控制吞吐量的收集器。

停頓時(shí)間和吞吐量不可能同時(shí)調(diào)優(yōu)。我們一方買(mǎi)希望停頓時(shí)間少,另外一方面希望吞吐量高,其實(shí)這是矛盾的。因?yàn)椋涸贕C的時(shí)候,垃圾回收的工作總量是不變的,如果將停頓時(shí)間減少,那頻率就會(huì)提高;既然頻率提高了,說(shuō)明就會(huì)頻繁的進(jìn)行GC,那吞吐量就會(huì)減少,性能就會(huì)降低。

吞吐量:CPU用于用戶代碼的時(shí)間/CPU總消耗時(shí)間的比值,即=運(yùn)行用戶代碼的時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間)。比如,虛擬機(jī)總共運(yùn)行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。

4、G1收集器:

  是當(dāng)今收集器發(fā)展的最前言成果之一,直到j(luò)dk1.7,sun公司才認(rèn)為它達(dá)到了足夠成熟的商用程度。

5、CMS收集器:(老年代收集器)

CMS收集器(Concurrent Mark Sweep:并發(fā)標(biāo)記清除)是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。適合應(yīng)用在互聯(lián)網(wǎng)站或者B/S系統(tǒng)的服務(wù)器上,這類(lèi)應(yīng)用尤其重視服務(wù)器的響應(yīng)速度,希望系統(tǒng)停頓時(shí)間最短。

七、Java堆內(nèi)存劃分:

Java 中的堆是 JVM 所管理的***的一塊內(nèi)存空間,主要用于存放各種類(lèi)的實(shí)例對(duì)象。

在 Java 中,堆被劃分成兩個(gè)不同的區(qū)域:年輕代 ( Young )、老年代 ( Tenured)。年輕代 ( Young ) 又被劃分為三個(gè)區(qū)域:Eden、From Survivor、To Survivor。 這樣劃分的目的是為了使 JVM 能夠更好的管理堆內(nèi)存中的對(duì)象,包括內(nèi)存的分配以及回收。

1.年輕代

年輕代用來(lái)存放新近創(chuàng)建的對(duì)象,尺寸隨堆大小的增大和減小而相應(yīng)的變化,默認(rèn)值是保持為堆大小的1/15,可以通過(guò) -Xmn 參數(shù)設(shè)置年輕代為固定大小,也可以通過(guò) -XX:NewRatio 來(lái)設(shè)置年輕代與年老代的大小比例,年青代的特點(diǎn)是對(duì)象更新速度快,在短時(shí)間內(nèi)產(chǎn)生大量的“死亡對(duì)象”。

年輕代的特點(diǎn)是產(chǎn)生大量的死亡對(duì)象,并且要是產(chǎn)生連續(xù)可用的空間, 所以使用復(fù)制清除算法和并行收集器進(jìn)行垃圾回收.對(duì)年輕代的垃圾回收稱作初級(jí)回收 (minor gc)。

2.老年代

Full GC 是發(fā)生在老年代的垃圾收集動(dòng)作,所采用的是標(biāo)記-清除算法。

現(xiàn)實(shí)的生活中,老年代的人通常會(huì)比新生代的人 “早死”。堆內(nèi)存中的老年代(Old)不同于這個(gè),老年代里面的對(duì)象幾乎個(gè)個(gè)都是在 Survivor 區(qū)域中熬過(guò)來(lái)的,它們是不會(huì)那么容易就 “死掉” 了的。因此,F(xiàn)ull GC 發(fā)生的次數(shù)不會(huì)有 Minor GC 那么頻繁,并且做一次 Full GC 要比進(jìn)行一次 Minor GC 的時(shí)間更長(zhǎng)。 另外,標(biāo)記-清除算法收集垃圾的時(shí)候會(huì)產(chǎn)生許多的內(nèi)存碎片 ( 即不連續(xù)的內(nèi)存空間 ),此后需要為較大的對(duì)象分配內(nèi)存空間時(shí),若無(wú)法找到足夠的連續(xù)的內(nèi)存空間,就會(huì)提前觸發(fā)一次 GC 的收集動(dòng)作。

3.***代

***代是Hotspot虛擬機(jī)特有的概念,是方法區(qū)的一種實(shí)現(xiàn),別的JVM都沒(méi)有這個(gè)東西。在Java 8中,***代被徹底移除,取而代之的是另一塊與堆不相連的本地內(nèi)存——元空間。

***代或者“Perm Gen”包含了JVM需要的應(yīng)用元數(shù)據(jù),這些元數(shù)據(jù)描述了在應(yīng)用里使用的類(lèi)和方法。注意,***代不是Java堆內(nèi)存的一部分。***代存放JVM運(yùn)行時(shí)使用的類(lèi)。***代同樣包含了Java SE庫(kù)的類(lèi)和方法。***代的對(duì)象在full GC時(shí)進(jìn)行垃圾收集。

八、類(lèi)加載機(jī)制:

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

對(duì)應(yīng)常見(jiàn)筆試題

注意:子類(lèi)初始化問(wèn)題:滿足主動(dòng)調(diào)用,即父類(lèi)訪問(wèn)子類(lèi)中的靜態(tài)變量、方法,子類(lèi)才會(huì)初始化;否則僅父類(lèi)初始化。

注意:訪問(wèn)類(lèi)或接口的靜態(tài)變量(特例:如果是用static final修飾的常量,那就不會(huì)對(duì)類(lèi)進(jìn)行顯式初始化。static final 修改的變量則會(huì)做顯式初始化)

上面的運(yùn)行效果顯示,由于c是final static修飾的靜態(tài)常量,所以根本就沒(méi)有調(diào)用靜態(tài)代碼塊里面的內(nèi)容,也就是說(shuō),沒(méi)有對(duì)這個(gè)類(lèi)進(jìn)行顯式初始化。


分享文章:面試重點(diǎn):Java虛擬機(jī)常見(jiàn)問(wèn)題詳解
當(dāng)前URL:http://www.5511xx.com/article/ccdjejj.html