最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2021年07月01日 09:45:32   作者:太子爺哪吒  
這篇文章主要為大家分享了最有價值的6道JVM面試題,涵蓋內容全面,包括數據結構和算法相關的題目、經典面試編程題等,對hashCode方法的設計、垃圾收集的堆和代進行剖析,感興趣的小伙伴們可以參考一下

1. JVM是如何判斷對象是否可回收

垃圾收集器在做垃圾回收的時候,首先需要判斷一個對象是存活狀態(tài)還是死亡狀態(tài),死亡的對象將會被標識為垃圾數據并等待收集器進行清除。

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

  • 引用計數器法:

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

  • 可達性分析算法:

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

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

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

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

標記清除法:

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

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

標記整理法:

基本步驟和標記清除類似,但是多了一步整理的步驟,讓所有村后的對象都向一端移動,然后清除掉不需要的內存。

它解決了內存碎片的問題,但是需要頻繁的移動存活的對象,效率就比較低了。

復制算法:

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

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

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

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

對于新生代來說采用了復制算法,因為對于新生代來說每次垃圾回收的存活的對象是比較少的,所以采用復制算法較好,而老年代的話,則采用了標記整理法。

  • 首先對象會先分配在eden區(qū),
  • 然后再新生代空間不足時,會發(fā)生一次minor gc算法將存活的對象復制到幸存區(qū)s1中,并使存活的對象的年齡加1,然后s1和s0交換,。
  • 在對象壽命超過閾值最大15時,就會晉升至老年代。
  • 而當老年代的空間不足時,會先嘗試觸發(fā)一次minor gc,如果空間還是不足的話。就會出發(fā)full gc ,而此時的stw會更長。

3. 你知道有什么垃圾收集器嗎?

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

作用于新生代的:

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

特點是簡單和高效,并且本身的運行對內存要求不高,因此它在客戶端模式下使用的比較多。

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

作用于老年代的:

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

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

  • Garbage First(簡稱 G1)收集器是歷史發(fā)展的產物,也是一款更先進的垃圾收集器,主要面向服務端應用的垃圾收集器,是基于基于標記-整理算法實現,不產生內存碎片。它將內存劃分為多個 Region 分區(qū),回收時則以分區(qū)為單位進行回收,這樣它就可以用相對較少的時間優(yōu)先回收包含垃圾最多區(qū)塊。此外,G1收集器不同于之前的收集器的一個重要特點是:G1回收的范圍是整個Java堆(包括新生代,老年代),而前六種收集器回收的范圍僅限于新生代或老年代。從 JDK 9 之后也成了官方默認的垃圾收集器,官方也推薦使用 G1 來代替選擇 CMS 收集器。

4. 那你知道什么時候才會觸發(fā)Full GC

1.在老年代空間不足的時候:

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

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

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

3.在永久代空間滿

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

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

4.在CMS垃圾收集器出現promotion failed(晉升失?。┖?code>concurrent mode failure(并發(fā)模式故障)

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

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

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

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

5. JVM中四種引用你有了解過嗎?

  • 強引用:垃圾收集器不會回收被強引用的對象。

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

當一個對象被強引用變量引用時,它處于可達狀態(tài),它是不可能被垃圾回收機制回收的即使在內存不足的情況下,JVM寧愿拋出OutOfMemory錯誤也不會回收這種對象。

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

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

  • 弱引用:具有弱引用的對象擁有更短暫的生命周期。在沒有被強引用對象,只能存活在下一次垃圾收集器前。無論內存夠不夠。

弱引用需要用 WeakReference 類來實現,它比軟引用的生存期更短,對于只有弱引用的對象來說,只要垃圾回收機制一運行,不管 JVM 的內存空間是否足夠,總會回收該對象占用的內存。

  • 虛引用:無法通過虛引用取得一個對象實例,設置虛引用的目的是為了能在這個對象被垃圾收集器回收時收到一個通知。 虛引用的主要作用是跟蹤對象被垃圾回收的狀態(tài)。

6. 說說你知道的幾種主要的JVM參數

1.堆設置

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -XX:NewSize=n:設置新生代大小
  • **-XX:NewRatio=n:**設置年輕代和年老代的比值。如:為3,表示新生代與老年代比值為1:3,新生代占整個新生代老年代和的1/4
  • -XX:SurvivorRatio=n:新生代中Eden區(qū)與兩個Survivor區(qū)的比值。注意Survivor區(qū)有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區(qū)占整個新生代的1/5
  • -XX:MaxPermSize=n:設置持久代大小

2.收集器設置

  • -XX:+UseSerialGC:設置串行收集器
  • -XX:+UseParallelGC:設置并行收集器
  • -XX:+UseParalledlOldGC:設置并行老年代收集器
  • -XX:+UseConcMarkSweepGC:設置并發(fā)收集器

3.并行收集器設置

  • -XX:ParallelGCThreads=n:設置并行收集器收集時使用的CPU數。并行收集線程數。
  • -XX:MaxGCPauseMillis=n:設置并行收集最大暫停時間
  • -XX:GCTimeRatio=n:設置垃圾回收時間占程序運行時間的百分比。公式為1/(1+n)

4.并發(fā)收集器設置

  • -XX:+CMSIncrementalMode:設置為增量模式。適用于單CPU情況。
  • -XX:ParallelGCThreads=n:設置并發(fā)收集器新生代收集方式為并行收集時,使用的CPU數。并行收集線程數。

5.JVM 調優(yōu)的參數

  • **-Xms2g:**初始化推大小為 2g;
  • **-Xmx2g:**堆最大內存為 2g;
  • **-XX:NewRatio=4:**設置年輕的和老年代的內存比例為 1:4;
  • **-XX:SurvivorRatio=8:**設置新生代 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 詳細信息。

總結

本篇文章就到這里了,如果這篇文章對你也有所幫助,希望您可以多多關注腳本之家的更多內容!

相關文章

最新評論

射阳县| 麟游县| 麻阳| 民勤县| 甘泉县| 鞍山市| 绩溪县| 临海市| 林甸县| 新巴尔虎左旗| 拉萨市| 剑河县| 廊坊市| 高台县| 溆浦县| 永康市| 潞城市| 晋城| 泸西县| 鄱阳县| 都昌县| 乌鲁木齐市| 孟村| 耿马| 海门市| 乐都县| 昆明市| 永定县| 游戏| 东平县| 瑞金市| 昭通市| 杭锦旗| 香格里拉县| 黄平县| 建瓯市| 曲水县| 东宁县| 增城市| 通州市| 江永县|