新聞中心

在黎川等地區(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


咨詢
建站咨詢
