您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么觸發YoungGC或FullGC操作”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么觸發YoungGC或FullGC操作”吧!
JAVA的垃圾回收需要完成三件事情:
1、哪些內存需要回收
2、什么時候回收
3、如何回收
下面就從這三個問題出發去了解Java的垃圾回收機制。
在垃圾回收之前,首要的問題是確定哪些垃圾需要被回收,現在Java通過根搜索算法(GC Roots Tracing)來判斷一個對象是否存活,這個算法的思路就是通過一系列名為“GC Roots”的對象作為起始點,從這些節點向下搜索,當GC Roots到達不了這個某個對象時(或者說某個對象沒有被任何其他對象所引用),就證明這個對象是不可用的,這些對象會被判定為需要回收的對象。
如圖,ObjC是不可達的,這個對象就是需要被回收的對象。
在Java語言中,可作為GC Roots的對象包括下面這些:
1、虛擬機棧(棧幀中的本地變量表)中引用的對象
2、方法區中的類靜態屬性引用的對象
3、方法區中的常量引用的對象
4、本地方法棧(Native方法)引用的對象
關于如何回收的問題,我參考了《深入理解Java虛擬機》,根搜索算法中不可達的對象,并不是立刻就會被回收,而是會經過一次標記:
如果對象沒有覆蓋finalize()方法,或者finalize()方法已經被調用,虛擬機會判定這個對象沒必要執行finalize(),在這一次標記中該對象不會被回收。
如果這個對象被標記為有必要執行finalize()方法時,它會被放置在一個名為F-Queue的隊列中,稍后由虛擬機進行垃圾回收。
但是這個對象還有最后一次逃脫的機會,當在F-Queue時,虛擬機會對F-Queue中的對象作小規模的標記,如果發現此時某個對象又可達了,就會逃過GC的命運。
如何回收垃圾的問題歸根結底就是垃圾回收算法如何回收垃圾的問題。這里主要介紹三種垃圾回收算法的執行思路:
這種算法分為標記和清除兩個階段,首先標記出所有需要回收的對象,在標記完成后統一回收掉被標記的對象。
看圖就可以明白了,這個算法的問題在于,清除之后會產生大量不連續的空間碎片。
復制算法將內存分為兩塊,每次使用其中一塊,垃圾回收時,將正在使用的那塊內存中存活的內存放入另一塊內存中,然后清空原內存塊,圖示圖下: 復制算法被廣泛應用于新生代的垃圾回收,由于新生代的對象有百分之98左右都是要被回收的,因此新生代的內存會被分為一塊Eden空間和兩塊Survivor空間,比例為8:1:1。
第一次YGC只回收eden區域,回收后大多數(百分之九十八左右)的對象會被回收,活著的對象通過復制算法進入Survivor0(后續用S0和S1代替)。再次YGC后,eden+S0中活著的對象進入S1。再次YGC,eden+S1中活著的對象進入到S0。依次循環
標記-整理算法分為標記、整理、清除三步,第一步也是標記出可回收的對象,然后讓存活的對象移到一邊,然后直接清理掉邊界外的垃圾。
標記整理算法被廣泛應用于老年代的垃圾回收。
YoungGC的觸發時常在發生,當新生代的Eden區滿了之后就會觸發YoungGC。
FullGC在多個情況下都會被觸發:
1、發生Young GC之前進行檢查,如果“老年代可用的連續內存空間” < “新生代歷次Young GC后升入老年代的對象總和的平均大小”,說明本次Young GC后可能升入老年代的對象大小,可能超過了老年代當前可用內存空間,此時會觸發FullGC
2、當老年代沒有足夠空間存放對象時,會觸發一次FullGC
3、如果元空間區域的內存達到了所設定的閾值-XX:MetaspaceSize=,也會觸發FullGC。
到此,相信大家對“怎么觸發YoungGC或FullGC操作”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。