日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

垃圾回收的核心知識(shí)點(diǎn)解析

作者:手插口袋誰(shuí)也不愛(ài)? 更新時(shí)間: 2023-07-22 編程語(yǔ)言

目錄

  • 檢測(cè)垃圾
    • 引用計(jì)數(shù)算法
    • 可達(dá)性分析算法
  • 回收垃圾
    • 標(biāo)記清除算法
    • 復(fù)制算法
    • 標(biāo)記整理算法
    • 分代算法

Java運(yùn)行時(shí)內(nèi)存中的程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧這三部分區(qū)域其生命周期與相關(guān)線程有關(guān),隨線程而生,隨線程而滅。而程序計(jì)數(shù)器就是一個(gè)單純存地址的整數(shù)也不需要關(guān)心,因此我們GC(垃圾回收)的主要目標(biāo)就是堆(堆中存放著幾乎所有實(shí)例對(duì)象)!

檢測(cè)垃圾

一個(gè)對(duì)象,如果后續(xù)不再被使用且沒(méi)有引用指向它,就可以認(rèn)為是垃圾。
有以下方法可知對(duì)象是否有引用指向:

引用計(jì)數(shù)算法

在主流的JVM中沒(méi)有選用引用計(jì)數(shù)法來(lái)管理內(nèi)存,最主要的原因就是引用計(jì)數(shù)法無(wú)法解決對(duì)象的循環(huán)引用問(wèn)題 Python,PHP采取了引用計(jì)數(shù)算法。

給對(duì)象增加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器就+1;當(dāng)引用失效時(shí),計(jì)數(shù)器就-1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不能再被使用的,即可被回收。

        Test test1 = new Test();
        Test test2 = test1;
        Test test3 = test1;
        Test test4 = test1;

在這里插入圖片描述

此算法存在兩個(gè)缺陷:

  1. 浪費(fèi)內(nèi)存空間
  2. 存在循環(huán)引用的情況
    用一個(gè)例子來(lái)解釋一下循環(huán)引用的問(wèn)題:
class Test {
 public Test test;
}
        Test test1 = new Test();
        Test test2 = new Test();
        test1.test=test2;
        test2.test=test1;

在這里插入圖片描述
此時(shí)test1與test2 銷毀了,兩個(gè)對(duì)象的引用計(jì)數(shù)分別減一。
在這里插入圖片描述
此時(shí)這兩個(gè)對(duì)象的引用計(jì)數(shù)不為0,不能作為垃圾且無(wú)法使用,陷入了一個(gè)邏輯上的循環(huán)。

可達(dá)性分析算法

通過(guò)一系列稱為"GC Roots"的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索走過(guò)的路徑稱之為"引用鏈",當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何的引用鏈相連時(shí)(從GC Roots到這個(gè)對(duì)象不可達(dá))時(shí),證明此對(duì)象是不可用的

在這里插入圖片描述
在java中,可作為GC Roots(垃圾回收根對(duì)象)的對(duì)象有以下幾種:

  1. 棧上的局部變量
  2. 常量池中引用的對(duì)象
  3. 方法區(qū)中類靜態(tài)屬性引用的對(duì)象

只有從GC Roots對(duì)象開(kāi)始,通過(guò)引用鏈可達(dá)的對(duì)象才被認(rèn)為是存活的,而無(wú)法通過(guò)引用鏈訪問(wèn)的對(duì)象則會(huì)被判定為垃圾,并進(jìn)行回收。

缺點(diǎn):

  1. 遍歷開(kāi)銷:可達(dá)性分析算法需要遍歷整個(gè)對(duì)象圖以確定每個(gè)對(duì)象的可達(dá)性。對(duì)于大型堆和復(fù)雜的引用關(guān)系,遍歷開(kāi)銷可能非常大,特別是在全局垃圾回收中。這可能會(huì)導(dǎo)致垃圾回收的性能下降。
  2. 延遲回收:可達(dá)性分析算法需要遍歷整個(gè)對(duì)象圖,從GC Roots開(kāi)始,逐個(gè)檢查每個(gè)對(duì)象的引用關(guān)系。這個(gè)過(guò)程可能需要消耗大量的時(shí)間,且在垃圾回收期間,應(yīng)用程序的執(zhí)行會(huì)被暫停(STW - Stop-The-World)。因此,可達(dá)性分析算法可能導(dǎo)致較高的延遲,影響程序的響應(yīng)性能。

回收垃圾

標(biāo)記清除算法

算法分為"標(biāo)記"和"清除"兩個(gè)階段 : 首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。
回收前:
在這里插入圖片描述
回收后:
在這里插入圖片描述
在這里插入圖片描述
不足:

  1. 標(biāo)記和清除這兩個(gè)過(guò)程的效率都不高。
  2. 標(biāo)記清除后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行中需要分配較大對(duì)象時(shí),無(wú)法找到足夠連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集。

復(fù)制算法

"復(fù)制"算法是為了解決"標(biāo)記-清理"的效率問(wèn)題。它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。
簡(jiǎn)單來(lái)說(shuō)復(fù)制算法就是把不是垃圾的對(duì)象拷貝到未使用的那一邊,然后再統(tǒng)一釋放剛才使用過(guò)的那一塊區(qū)域

缺點(diǎn):

  1. 內(nèi)存利用率比較低。
  2. 如果當(dāng)前區(qū)域的大部分對(duì)象都需要保留垃圾很少,那么此時(shí)的復(fù)制成本就比較高。

標(biāo)記整理算法

標(biāo)記整理算法的基本流程:

  1. 標(biāo)記:從根對(duì)象開(kāi)始,通過(guò)可達(dá)性分析算法,標(biāo)記所有從根對(duì)象可達(dá)的存活對(duì)象。標(biāo)記過(guò)程中,通常使用標(biāo)記位(標(biāo)記狀態(tài))來(lái)標(biāo)記對(duì)象是否為存活對(duì)象。

  2. 整理:將所有存活對(duì)象移到堆的一端,緊湊排列,以便釋放出連續(xù)的一段內(nèi)存空間。在移動(dòng)存活對(duì)象時(shí),需要更新對(duì)這些對(duì)象的引用,確保引用指向移動(dòng)后的新位置。

  3. 更新引用:在堆中,遍歷所有存活對(duì)象的引用,將其指向新的位置。這是為了避免懸掛指針(引用指向被移動(dòng)或已回收的對(duì)象)的問(wèn)題。

  4. 釋放未標(biāo)記的對(duì)象:在整理后的堆中,所有沒(méi)有被標(biāo)記的對(duì)象都可以被認(rèn)為是垃圾對(duì)象,可以直接被回收。

優(yōu)點(diǎn):解決了內(nèi)存碎片問(wèn)題。
缺點(diǎn):搬運(yùn)復(fù)制開(kāi)銷比較大。

分代算法

分代算法主要基于一種觀察:大部分對(duì)象的生命周期都比較短暫。根據(jù)這個(gè)觀察,分代算法將堆內(nèi)存劃分為不同的代(Generation),每一代中對(duì)象的生命周期不同,并且根據(jù)對(duì)象的生命周期將不同的垃圾回收策略應(yīng)用于不同的代中。

一般來(lái)說(shuō),分代堆內(nèi)存被劃分為年輕代(Young Generation)和老年代(Old Generation)兩個(gè)主要部分
年輕代
年輕代是存放新創(chuàng)建的對(duì)象的地方,大部分對(duì)象在創(chuàng)建后很快就變?yōu)槔鴮?duì)象。年輕代通常進(jìn)一步分為Eden區(qū)和兩個(gè)Survivor區(qū)。新創(chuàng)建的對(duì)象首先放入Eden區(qū),當(dāng)Eden區(qū)滿時(shí),不會(huì)被回收的對(duì)象會(huì)被轉(zhuǎn)移到一個(gè)Survivor區(qū)。當(dāng)一個(gè)Survivor區(qū)滿時(shí),其中的存活對(duì)象會(huì)被復(fù)制到另一個(gè)Survivor區(qū)或者老年代。經(jīng)過(guò)多次垃圾回收后依然存活的對(duì)象將晉升到老年代。
年輕代通常采用復(fù)制算法(Copying)作為垃圾回收策略,因?yàn)樾聞?chuàng)建的對(duì)象的生命周期短暫,復(fù)制算法可以更好地利用對(duì)象的特點(diǎn)。
老年代
老年代是存放存活時(shí)間較長(zhǎng)的對(duì)象的地方,老年代的對(duì)象生命周期較長(zhǎng),垃圾回收頻率相對(duì)較低。對(duì)于老年代的垃圾回收,可以采用標(biāo)記-清除(Mark-Sweep)或者標(biāo)記-整理(Mark-Compact)等算法。

分代算法通過(guò)區(qū)分不同代的對(duì)象,針對(duì)不同代采取不同的垃圾回收策略,可以提高垃圾回收效率和系統(tǒng)性能。年輕代的頻繁垃圾回收可以快速回收新創(chuàng)建對(duì)象,老年代的較少回收可以減少全局垃圾回收的引發(fā),提高應(yīng)用程序的響應(yīng)性。這種分代垃圾回收策略在大多數(shù)的垃圾收集器中都有應(yīng)用。

原文鏈接:https://blog.csdn.net/st200112266/article/details/131728218

  • 上一篇:沒(méi)有了
  • 下一篇:沒(méi)有了
欄目分類
最近更新