您好,登錄后才能下訂單哦!
小編給大家分享一下JVM垃圾收集器算法是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
垃圾收集器用于清除垃圾的算法有:標記-清除算法、復制算法、標記-整理算法。
用于針對對象不同的存活周期而分代的算法有:分代收集算法。這個算法把Java堆分為新生代和老年代。
1.1 標記-清除算法(Mark-Sweep)
標記-清除算法應該是最符合我們人一開始處理垃圾的思路的算法,例如我們想清除房間的垃圾,我們肯定是先定位(對應標記)哪些是垃圾,然后把這些垃圾之后扔了(對應清除),簡單粗暴,剩下的不是垃圾的東西我也懶得理,不管了哈哈哈。
當然有的人說我打掃房間會先整理不是垃圾的東西然后把垃圾扔了...你走錯片場了請去標記-整理片場(勤勞的孩子)。
這算法有兩個缺點
1.標記和清除的效率不高,按這種思路是一個一個標記過去,并且掃描哪些是標記過得然后才清除了
2.空間碎片問題,看上圖整理后中間空了好多,這樣會使得比較大的對象要申請比較多的連續空間的時候申請不到,明明你空間還很足的。然后導致又一次GC。
1.2 復制算法
復制算法等于說根據標記-清除算法的不足之處進行了改進。簡單的來說它把空間切成了兩半,一次我就用一半,一半滿了我就把活著的對象放在另一半按順序放,然后無腦的把剛才使用的那一半空間一次清理干凈,然后保留著存活的那些對象的內存空間換上去使用。這樣就沒了標記-清除算法的空間碎片問題。
虛擬機基本上用這種算法來回收新生代,但是切一半空間利用率太低了,一次就只能用一半。所以在HotSpot中是把這一塊空間分為3塊,一塊Eden,兩塊Survivor。
因為正常情況下新生代的大部分對象都是短命鬼,所以能活下來的不多,所以默認的空間劃分比例是8:1:1。用法就是每次只使用Eden和一塊Survivor,然后把活下來的對象都扔到另一塊Survivor。再清理Eden和之前的那塊Survivor。
然后再把Eden和存放存活對象的那一塊Survivor用來迎接新的對象。就等于每次回收了之后都會對調一下兩個Survivor。
但是事情總有意外,萬一這波對象短命鬼較少,存活下來的很多,那一個Survivor放不下,所以還有個擔保機制,就像我們現實生活中的擔保人,你還不起了擔保人上!這個擔保人就是老年代,也就是Survivor放不下了就放老年代去。
那為什么虛擬機基本上用這種算法來回收新生代呢?就是因為新生代的對象大部分存活時間不長,所以每次GC的時候復制的比較少,效率高啊,每次就復制一點點對象到Survivor。
那要是到老年代也就是一些老不死的對象那用復制效率就低了啊,首先8:1:1這種分法就不合適了,因為每次存活下來的對象會很多,1就放不下了,你可能就得"五五開"分了,那"五五開"之分也就算了,因為每次對象基本上都活著,所以每次復制等于復制一半空間的對象。效率低啊。
還有,新生代有老年代做擔保啊,多了的對象可以放到老年代,而老年代不行啊,沒有依靠了。所以就又有了下面的算法。
1.3 標記-整理算法(Mark-Compact)
標記-整理算法的思路也是和標記-清除算法一樣,先標記那些需要清除的對象,但是后續步驟不一樣,它是整理,對就是像上面說的那些清除房間垃圾每次都會整理的人一樣那么勤勞。
每次會移動所有存活的對象,且按照內存地址次序依次排列,也就是把活著的對象都像一端移動,然后將末端內存地址以后的內存全部回收。所以用了它也就沒有空間碎片的問題了。
1.4 分代收集算法
這算法就是把Java堆分為新生代和老年代,這樣好根據每個代的對象存活時間特點上不同的收集算法。
所以一般新老代就是用復制算法。老年代用標記-清除或標記-整理算法。
以上是“JVM垃圾收集器算法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。