国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁技術(shù)文章
文章詳情頁

每日六道java新手入門面試題,通往自由的道路--JVM

瀏覽:124日期:2022-08-10 17:00:22
目錄1. JVM是如何判斷對(duì)象是否可回收2. 你知道有什么垃圾回收的常見算法嗎?3. 你知道有什么垃圾收集器嗎?4. 那你知道什么時(shí)候才會(huì)觸發(fā)Full GC5. JVM中四種引用你有了解過嗎?6. 說說你知道的幾種主要的JVM參數(shù)1.堆設(shè)置2.收集器設(shè)置3.并行收集器設(shè)置4.并發(fā)收集器設(shè)置5.JVM 調(diào)優(yōu)的參數(shù)總結(jié)1. JVM是如何判斷對(duì)象是否可回收

垃圾收集器在做垃圾回收的時(shí)候,首先需要判斷一個(gè)對(duì)象是存活狀態(tài)還是死亡狀態(tài),死亡的對(duì)象將會(huì)被標(biāo)識(shí)為垃圾數(shù)據(jù)并等待收集器進(jìn)行清除。

而判斷一個(gè)對(duì)象是否為可回收狀態(tài)的常用算法有兩個(gè):引用計(jì)數(shù)器法和可達(dá)性分析算法。

引用計(jì)數(shù)器法:

在 Java 中,引用和對(duì)象是有關(guān)聯(lián)的,通過引用計(jì)數(shù)來判斷一個(gè)對(duì)象是否可以回收。它在創(chuàng)建對(duì)象時(shí)關(guān)聯(lián)一個(gè)與之相對(duì)應(yīng)的計(jì)數(shù)器,當(dāng)此對(duì)象被使用時(shí)加 1,相反銷毀時(shí) -1。當(dāng)此計(jì)數(shù)器為 0 時(shí),則表示此對(duì)象未使用,可以被垃圾收集器回收。其優(yōu)點(diǎn)是垃圾回收比較及時(shí),實(shí)時(shí)性比較高,只要對(duì)象計(jì)數(shù)器為 0,則可以直接進(jìn)行回收操作;而缺點(diǎn)是無法解決循環(huán)引用的問題。

可達(dá)性分析算法:

主要是從GC Root的對(duì)象為起點(diǎn)出發(fā),然后開始向下搜索,搜索走過的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Root之間沒有任何引用鏈的時(shí)候,代表這個(gè)對(duì)象不可以用,判斷為垃圾,就會(huì)被GC回收。

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

虛擬機(jī)棧中引用的對(duì)象 方法區(qū)類靜態(tài)屬性引用的對(duì)象 方法區(qū)常量池引用的對(duì)象 本地方法棧 JNI 引用的對(duì)象

每日六道java新手入門面試題,通往自由的道路--JVM

2. 你知道有什么垃圾回收的常見算法嗎?

標(biāo)記清除法:

分為標(biāo)記?清除兩個(gè)階段,首先先標(biāo)記出所有需要回收的對(duì)象,然后在標(biāo)記完成后統(tǒng)一清除回收所有被標(biāo)記的對(duì)象。

它可能產(chǎn)生的問題呢標(biāo)記清除后,產(chǎn)生一些大量不連續(xù)的內(nèi)存碎片,導(dǎo)致可能以后后續(xù)的大內(nèi)存找不到足夠的連續(xù)內(nèi)存再導(dǎo)致提前又發(fā)生一次垃圾收集

標(biāo)記整理法:

基本步驟和標(biāo)記清除類似,但是多了一步整理的步驟,讓所有村后的對(duì)象都向一端移動(dòng),然后清除掉不需要的內(nèi)存。

它解決了內(nèi)存碎片的問題,但是需要頻繁的移動(dòng)存活的對(duì)象,效率就比較低了。

復(fù)制算法:

將可用的內(nèi)存分為一半,每次只使用一個(gè)區(qū)域。將需要存活的對(duì)象復(fù)制到另一個(gè)對(duì)象中去。

這種方法也是可以解決了內(nèi)存碎片問題,但是內(nèi)存對(duì)半分了,而且對(duì)象存活率高的對(duì)象需要頻繁復(fù)制。

基于前面的算法的話,JVM采用一個(gè)分代算法的形式:

對(duì)于JVM的堆來說分為了新生代和老年代兩個(gè)區(qū)域,而新生代也還分了eden區(qū)和兩個(gè)幸存區(qū),他們比例是8:1:1,

對(duì)于新生代來說采用了復(fù)制算法,因?yàn)閷?duì)于新生代來說每次垃圾回收的存活的對(duì)象是比較少的,所以采用復(fù)制算法較好,而老年代的話,則采用了標(biāo)記整理法。

首先對(duì)象會(huì)先分配在eden區(qū), 然后再新生代空間不足時(shí),會(huì)發(fā)生一次minor gc算法將存活的對(duì)象復(fù)制到幸存區(qū)s1中,并使存活的對(duì)象的年齡加1,然后s1和s0交換,。 在對(duì)象壽命超過閾值最大15時(shí),就會(huì)晉升至老年代。 而當(dāng)老年代的空間不足時(shí),會(huì)先嘗試觸發(fā)一次minor gc,如果空間還是不足的話。就會(huì)出發(fā)full gc ,而此時(shí)的stw會(huì)更長。3. 你知道有什么垃圾收集器嗎?

常見的垃圾收集器有:其中用于回收新生代的收集器有Serial、PraNew、Parallel Scavenge,而回收老年代的收集器有Serial Old、Parallel Old、CMS,最后還有一個(gè)可以用于回收整個(gè)Java堆的G1收集器。

每日六道java新手入門面試題,通往自由的道路--JVM

作用于新生代的:

Serial 收集器屬于最早期的垃圾收集器,也是 JDK 1.3 版本之前唯一的垃圾收集器。它是單線程的垃圾收集器,采用復(fù)制算法,其意味著單線程是指在進(jìn)行垃圾回收時(shí)所有的工作線程必須暫停,直到垃圾回收結(jié)束為止。

特點(diǎn)是簡(jiǎn)單和高效,并且本身的運(yùn)行對(duì)內(nèi)存要求不高,因此它在客戶端模式下使用的比較多。

sParNew 收集器實(shí)際上是 Serial 收集器的多線程并行版本,也是采用復(fù)制算法。 Parallel Scavenge 收集器和 ParNew 收集器類似,它也是一個(gè)并行運(yùn)行的垃圾回收器;不同的點(diǎn)在于該收集器關(guān)注的側(cè)重點(diǎn)是實(shí)現(xiàn)一個(gè)可以控制的吞吐量。它的計(jì)算公式是:用戶運(yùn)行代碼的時(shí)間 / (用戶運(yùn)行代碼的時(shí)間 + 垃圾收集的時(shí)間)。比如用戶運(yùn)行的時(shí)間是 8 分鐘,垃圾回收運(yùn)行的時(shí)間是 2 分鐘,那么吞吐量就是 80%。Parallel Scavenge 收集器追目標(biāo)就是達(dá)到一個(gè)可控制的吞吐量,高吞吐量可以最高效率地利用CPU時(shí)候,盡快地完成程序的運(yùn)算任務(wù)。

作用于老年代的:

Serial Old 收集器為 Serial 收集器的老年代版本,而 Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本。兩者都是在老年代中采用這標(biāo)記—— 整理算法。 CMS(Concurrent Mark Sweep)以獲取最短回收停頓時(shí)間為目標(biāo),與Parallel Scavenge 收集器不同,是基于標(biāo)記 —— 清除算法實(shí)現(xiàn)。它強(qiáng)調(diào)的是提供最短的停頓時(shí)間,因此可能會(huì)犧牲一定的吞吐量。它主要應(yīng)用在 Java Web 項(xiàng)目中,它滿足了系統(tǒng)需要短時(shí)間停頓的要求,以此來提高用戶的交互體驗(yàn)。CMS 工作機(jī)制相比其他的垃圾收集器來說更復(fù)雜。整個(gè)過程分為以下 4 個(gè)階段: 初始標(biāo)記(CMS initial mark):標(biāo)記 GC Roots 能直接關(guān)聯(lián)到的對(duì)象并發(fā)標(biāo)記(CMS concurrent mark):進(jìn)行 GC Roots Tracing重新標(biāo)記(CMS remark):修正并發(fā)標(biāo)記期間的變動(dòng)部分并發(fā)清除(CMS concurrent sweep):清除 GC Roots 不可達(dá)對(duì)象,和用戶線程一起工作,不需要暫停工作線程。

作用于整個(gè)Java堆包括新生代和老年代的。

Garbage First(簡(jiǎn)稱 G1)收集器是歷史發(fā)展的產(chǎn)物,也是一款更先進(jìn)的垃圾收集器,主要面向服務(wù)端應(yīng)用的垃圾收集器,是基于基于標(biāo)記-整理算法實(shí)現(xiàn),不產(chǎn)生內(nèi)存碎片。它將內(nèi)存劃分為多個(gè) Region 分區(qū),回收時(shí)則以分區(qū)為單位進(jìn)行回收,這樣它就可以用相對(duì)較少的時(shí)間優(yōu)先回收包含垃圾最多區(qū)塊。此外,G1收集器不同于之前的收集器的一個(gè)重要特點(diǎn)是:G1回收的范圍是整個(gè)Java堆(包括新生代,老年代),而前六種收集器回收的范圍僅限于新生代或老年代。從 JDK 9 之后也成了官方默認(rèn)的垃圾收集器,官方也推薦使用 G1 來代替選擇 CMS 收集器。4. 那你知道什么時(shí)候才會(huì)觸發(fā)Full GC

1.在老年代空間不足的時(shí)候:

老年代空間只有在新生代對(duì)象發(fā)生minor Gc轉(zhuǎn)入或者是直接創(chuàng)建為大對(duì)象、大數(shù)組時(shí)出現(xiàn)空間不足的現(xiàn)象,當(dāng)JVM執(zhí)行Full GC后空間仍然不足,則拋出如下錯(cuò)誤:java.lang.OutOfMemoryError: Java heap space。

解決措施:盡量做到讓對(duì)象在Minor GC階段被回收、讓對(duì)象在新生代多存活一段時(shí)間及不要?jiǎng)?chuàng)建過大的對(duì)象及數(shù)組。

2.在我們程序中直接調(diào)用了System.gc, 也會(huì)直接出發(fā)Full GC。

3.在永久代空間滿

永久代中存放的為一些class的信息等,當(dāng)系統(tǒng)中要加載的類、反射的類和調(diào)用的方法較多時(shí),永久代空間可能會(huì)被占滿,在未配置的時(shí)候采用這CMS垃圾收集器的情況下會(huì)執(zhí)行Full GC。如果經(jīng)過Full GC仍然回收不了,那么JVM會(huì)拋出如下錯(cuò)誤信息:java.lang.OutOfMemoryError: PermGen space。

解決措施:可采用的方法為增大永久代空間或轉(zhuǎn)為使用CMS GC。

4.在CMS垃圾收集器出現(xiàn)promotion failed(晉升失敗)和concurrent mode failure(并發(fā)模式故障)

對(duì)于如果我們采用CMS垃圾收集器進(jìn)行老年代GC的程序而言,我們就需要主要在GC日志中是否有晉升失敗和并發(fā)模式故障兩種狀況,當(dāng)這兩種狀況出現(xiàn)時(shí)可能會(huì)觸發(fā)Full GC:

晉升失敗(promotion failed) 是在新生代進(jìn)行Minor GC時(shí),幸存區(qū)中放不下、而對(duì)象只能放入老年代,而此時(shí)老年代也放不下造成的。

concurrent mode failure是CMS轉(zhuǎn)悠的錯(cuò)誤,即并發(fā)清楚線程和工作線程同時(shí)工作,清理出來老年代的空間不足以存放由新生代晉升到老年代的對(duì)象。

解決措施:減少年輕代大小,避免放入老年代時(shí)需要分配大的空間,同時(shí)調(diào)整觸發(fā)Full GC時(shí)的比率以及將觸發(fā)CMS GC的閥值適當(dāng)增大

5. JVM中四種引用你有了解過嗎? 強(qiáng)引用:垃圾收集器不會(huì)回收被強(qiáng)引用的對(duì)象。

在 Java 中最常見的就是強(qiáng)引用, 把一個(gè)對(duì)象賦給一個(gè)引用變量,這個(gè)引用變量就是一個(gè)強(qiáng)引用。即在我們寫類似這樣User user = new User(),我們new出來的user對(duì)象就是一個(gè)強(qiáng)引用了!

當(dāng)一個(gè)對(duì)象被強(qiáng)引用變量引用時(shí),它處于可達(dá)狀態(tài),它是不可能被垃圾回收機(jī)制回收的即使在內(nèi)存不足的情況下,JVM寧愿拋出OutOfMemory錯(cuò)誤也不會(huì)回收這種對(duì)象。

軟引用:在沒有被強(qiáng)引用對(duì)象,當(dāng)系統(tǒng)要發(fā)生內(nèi)存溢出的異常之前,會(huì)將其列為回收范圍,進(jìn)行第二次回收。

軟引用需要用 SoftReference 類來實(shí)現(xiàn),對(duì)于只有軟引用的對(duì)象來說,當(dāng)系統(tǒng)內(nèi)存足夠時(shí)它不會(huì)被回收,當(dāng)系統(tǒng)內(nèi)存空間不足時(shí)它會(huì)被回收。軟引用通常用在對(duì)內(nèi)存敏感的程序中。

弱引用:具有弱引用的對(duì)象擁有更短暫的生命周期。在沒有被強(qiáng)引用對(duì)象,只能存活在下一次垃圾收集器前。無論內(nèi)存夠不夠。

弱引用需要用 WeakReference 類來實(shí)現(xiàn),它比軟引用的生存期更短,對(duì)于只有弱引用的對(duì)象來說,只要垃圾回收機(jī)制一運(yùn)行,不管 JVM 的內(nèi)存空間是否足夠,總會(huì)回收該對(duì)象占用的內(nèi)存。

虛引用:無法通過虛引用取得一個(gè)對(duì)象實(shí)例,設(shè)置虛引用的目的是為了能在這個(gè)對(duì)象被垃圾收集器回收時(shí)收到一個(gè)通知。 虛引用的主要作用是跟蹤對(duì)象被垃圾回收的狀態(tài)。6. 說說你知道的幾種主要的JVM參數(shù)1.堆設(shè)置 -Xms:初始堆大小 -Xmx:最大堆大小 -XX:NewSize=n:設(shè)置新生代大小 **-XX:NewRatio=n:**設(shè)置年輕代和年老代的比值。如:為3,表示新生代與老年代比值為1:3,新生代占整個(gè)新生代老年代和的1/4 -XX:SurvivorRatio=n:新生代中Eden區(qū)與兩個(gè)Survivor區(qū)的比值。注意Survivor區(qū)有兩個(gè)。如:3,表示Eden:Survivor=3:2,一個(gè)Survivor區(qū)占整個(gè)新生代的1/5 -XX:MaxPermSize=n:設(shè)置持久代大小2.收集器設(shè)置 -XX:+UseSerialGC:設(shè)置串行收集器 -XX:+UseParallelGC:設(shè)置并行收集器 -XX:+UseParalledlOldGC:設(shè)置并行老年代收集器 -XX:+UseConcMarkSweepGC:設(shè)置并發(fā)收集器3.并行收集器設(shè)置 -XX:ParallelGCThreads=n:設(shè)置并行收集器收集時(shí)使用的CPU數(shù)。并行收集線程數(shù)。 -XX:MaxGCPauseMillis=n:設(shè)置并行收集最大暫停時(shí)間 -XX:GCTimeRatio=n:設(shè)置垃圾回收時(shí)間占程序運(yùn)行時(shí)間的百分比。公式為1/(1+n)4.并發(fā)收集器設(shè)置 -XX:+CMSIncrementalMode:設(shè)置為增量模式。適用于單CPU情況。 -XX:ParallelGCThreads=n:設(shè)置并發(fā)收集器新生代收集方式為并行收集時(shí),使用的CPU數(shù)。并行收集線程數(shù)。5.JVM 調(diào)優(yōu)的參數(shù) **-Xms2g:**初始化推大小為 2g; **-Xmx2g:**堆最大內(nèi)存為 2g; **-XX:NewRatio=4:**設(shè)置年輕的和老年代的內(nèi)存比例為 1:4; **-XX:SurvivorRatio=8:**設(shè)置新生代 Eden 和 Survivor 比例為 8:2; **?XX:+UseParNewGC:**指定使用 ParNew + Serial Old 垃圾回收器組合; **-XX:+UseParallelOldGC:**指定使用 ParNew + ParNew Old 垃圾回收器組合; **-XX:+UseConcMarkSweepGC:**指定使用 CMS + Serial Old 垃圾回收器組合; **-XX:+PrintGC:**開啟打印 gc 信息; **-XX:+PrintGCDetails:**打印 gc 詳細(xì)信息。總結(jié)

本篇文章就到這里了,如果這篇文章對(duì)你也有所幫助,希望您可以多多關(guān)注好吧啦網(wǎng)的更多內(nèi)容!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 瓮安县| 连州市| 乳源| 南京市| 大埔区| 石渠县| 崇明县| 班玛县| 焉耆| 东源县| 桐柏县| 翼城县| 彰化县| 和静县| 樟树市| 杂多县| 东明县| 林周县| 鄂托克前旗| 古丈县| 浦北县| 保德县| 遂昌县| 新闻| 东乡| 新和县| 澎湖县| 湟源县| 呼伦贝尔市| 乌海市| 镇原县| 旅游| 德化县| 泰宁县| 明光市| 大城县| 上犹县| 云梦县| 雷山县| 海城市| 万安县|