日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

经典面试题:聊一聊垃圾回收算法

發(fā)布時間:2025/3/11 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 经典面试题:聊一聊垃圾回收算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關于垃圾回收算法的這道面試題,幾乎是所有 3 年以上的 Java 面試中必問的題目,甚至有些好一點的公司會在校招時問到面試者。那么本文就系統(tǒng)的講一下垃圾回收的算法,和 Hotspot 虛擬機執(zhí)行垃圾回收的一些實現(xiàn)細節(jié),比如安全點和安全區(qū)域等。

因為各個平臺的虛擬機操作內存的方法各不相同,且牽扯大量的程序實現(xiàn)細節(jié),所以本文不會過多的討論算法的具體實現(xiàn),只會介紹幾種算法思想及發(fā)展過程。

垃圾回收算法

1、標記-清除算法

標記-清除算法是最基礎的算法,像它的名字一樣算法分為“標記”和“清除”兩個階段,首先需要標記出所需要回收的對象,標記完成后統(tǒng)一收集被標記的對象。

優(yōu)點: 實現(xiàn)簡單。

缺點: 產生不連續(xù)的內存碎片;“標記”和“清除”的執(zhí)行效率都不高。

標記-清除算法執(zhí)行過程圖:

(本文圖片來自《深入理解Java虛擬機》)

2、復制算法

復制算法就是將內存分為大小相同的兩塊,當這一塊使用完了,就把當前存活的對象復制到另一塊,然后一次性清空當前區(qū)塊。

優(yōu)點: 執(zhí)行效率高。

缺點: 空間利用率低, 因為復制算法每次只能使用一半的內存。

3、標記-整理算法

也稱標記-壓縮算法,標記-整理算法采用和標記清除算法一樣的對象“標記”,但后續(xù)不會對可回收對象進行清理,而是將存活的對象往一端空閑空間移動,然后清理邊界以外的內存空間。

優(yōu)點: 解決了內存碎片問題,比復制算法空間利用率高。

缺點: 因為有局部對象移動,相對效率不高。

標記-整理算法執(zhí)行過程圖:

4、分代收集算法

目前商用虛擬機都采用的是分代收集的算法,這種算法按照對象存活周期把內存分為幾塊,一般Java中分為新生代和老年代。把存活率低的對象分到新生代使用復制算法提高垃圾回收的性能,老年代則存放存活率搞的對象,使用標記-清除和標記-整理的算法,提高內存空間使用率。

新生代和老生代的具體介紹和參數(shù)配置,后續(xù)的文章會詳細講解。

垃圾回收執(zhí)行細節(jié)

本節(jié)將詳細的介紹一下HotSpot虛擬機在執(zhí)行垃圾回收時的一些細節(jié),目的是讓讀者更好的理解Java虛擬機。

HotSpot虛擬機: 它是Sun JDK和OpenJDK自定的虛擬機,也是目前使用最廣泛的虛擬機。

垃圾回收流程: Java虛擬機在內存回收之前,為了保證內存的一致性,必須先暫停程序的執(zhí)行,也就是傳說中的Stop The World(簡稱STW),在使用可達性分析算法枚舉GC Roots,標記出死亡對象,再進行垃圾回收。

垃圾回收遇到的問題: 那既然是要暫停程序的運行,就一定要保證停止的時間足夠短,并且可控,不然帶來的災難將是毀滅性的。

解決方案: 顯然HotSpot在設計的時候也考慮到了這個問題,所以在JIT編譯的時候就會使用OopMap數(shù)據(jù)結構來記錄棧和寄存器上的引用,這樣虛擬機就直接知道了那些地方存放著對象的引用,如下圖,為我編譯String.hashCode()方法的部分本地代碼:

可以看出,使用OopMap數(shù)據(jù)結構存儲了普通對象的指針引用。

查看匯編的方法,啟動命令窗體執(zhí)行: java-XX:+UnlockDiagnosticVMOptions-XX:+PrintAssemblyYouTestClass

命令可能會報錯: Couldnotload hsdis-amd64.dll;librarynotloadable;PrintAssemblyisdisabled

報錯解決方法:使用編譯好的hsdis.dll放到:jre安裝目錄\bin\server目錄下即可,hsdis.dll地址地址:https://pan.baidu.com/s/1-D6u0gnUx291LXS3bHOorA

安全點(Safepoint)

在OopMap的協(xié)助下,HotSpot可以快速的完成GC Roots枚舉,但導致OopMap內容變化的指令很多,而且如果給每個對象生成對應的OopMap,會造成大量額外的空間,這會導致GC成本很高,所以HotSpot只會在“特定的位置”生成對應的OopMap,這些位置就成為“安全點”。

HotSpot也并不是任何時刻都會停頓下來進行GC,只會在程序都到底安全點之后才會GC,所以安全點的設置不能太少,讓GC等待時間太長,也不能太多增大運行時的成本。

安全點的兩種線程中斷方式

搶斷式中斷:不需要線程的執(zhí)行代碼去主動配合,當發(fā)生GC時,先強制中斷所有線程,然后如果發(fā)現(xiàn)某些線程未處于安全點,恢復程序運行,直到進入安全點為止。

主動式中斷:不強制中斷線程,只是簡單地設置一個中斷標記,各個線程在執(zhí)行時輪詢這個標記,一旦發(fā)現(xiàn)標記被改變(出現(xiàn)中斷標記)時,那么將運行到安全點后自己中斷掛起。目前所有商用虛擬機全部采用主動式中斷。

安全區(qū)域(Saferegion)

安全點機制僅僅是保證了程序執(zhí)行時不需要太長時間就可以進入一個安全點進行 GC 動作,但是當特殊情況時,比如線程休眠、線程阻塞等狀態(tài)的情況下,顯然HotSpot不可能一直等待被阻塞或休眠的線程正常喚醒執(zhí)行;此時就引入了安全區(qū)的概念。

安全區(qū)(Saferegion):安全區(qū)域是指在一段區(qū)域內,對象引用關系等不會發(fā)生變化,在此區(qū)域內任意位置開始GC都是安全的;線程運行時,首先標記自己進入了安全區(qū),然后在這段區(qū)域內,如果線程發(fā)生了阻塞、休眠等操作,HotSpot發(fā)起GC時將忽略這些處于安全區(qū)的線程。當線程再次被喚醒時,首先他會檢查是否完成了GC Roots枚舉(或這個GC過程),如果完成了就繼續(xù)執(zhí)行,否則將繼續(xù)等待直到收到可以安全離開的Safe Region的信號為止。

總結

前面講的垃圾回收器算法屬于基本功,要求面試者一定要熟練記憶的,而后面的垃圾收集器的執(zhí)行細節(jié)如果加分項,如果都能融會貫通的話,Offer 就離你又進一步了。

【End】

查看更多面試題內容,請訪問《Java最常見200+面試題全解析》,它包含的模塊有:

  • Java、JVM?最常見面試題解析

  • Spring、Spring?MVC、MyBatis、Hibernate?面試題解析

  • MySQL、Redis?面試題解析

  • RabbitMQ、Kafka、Zookeeper?面試解析

  • 微服務?Spring?Boot、Spring?Cloud?面試解析

掃描下面二維碼付費閱讀

關注下方二維碼,訂閱更多精彩內容。

轉發(fā)朋友圈,是對我最大的支持。

總結

以上是生活随笔為你收集整理的经典面试题:聊一聊垃圾回收算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。