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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

垃圾收集机制原理

發(fā)布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 垃圾收集机制原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄標(biāo)題

  • 1.可回收對象
    • 1、引用計(jì)數(shù)算法
    • 2、可達(dá)性分析算法
  • 2.垃圾收集算法
    • 1.標(biāo)記-清除算法
    • 2. 復(fù)制算法
    • 3.標(biāo)記-整理算法
    • 4. 分代收集算法
  • 3.新生代 老年代
  • 4.什么時候GC回收對象?

Java堆(Java Heap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對象實(shí)例,幾乎所有的對象實(shí)例都在這里分配內(nèi)存。
Java堆是垃圾收集器管理的主要區(qū)域,也被稱做“GC堆”(Garbage Collected Heap

Java回收對象涉及如何判斷哪些對象應(yīng)該回收,內(nèi)存的收集算法等。

1.可回收對象

在堆里面存放著Java世界中幾乎所有的對象實(shí)例,垃圾收集器在對堆進(jìn)行回收前,第一件事情就是要確定這些對象之中哪些 可回收。

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

給對象中添加一個引用計(jì)數(shù)器,每當(dāng)有一個地方引用它時,計(jì)數(shù)器值就加 1;當(dāng)引用失效時,計(jì)數(shù)器值就減1;任何時刻計(jì)數(shù)器為0的對象就是不可能再被使用的,主流的Java虛擬機(jī)里面沒有選用引用 計(jì)數(shù)算法來管理內(nèi)存,其中最主要的原因是它很難解決對象之間相互循環(huán)引用的問題。

2、可達(dá)性分析算法

是通過一系列的稱為"GC Roots"的對象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向 下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說,就 是從GC Roots到這個對象不可達(dá))時,則證明此對象是不可用的
在Java語言中,可作為GC Roots的對象包括下面幾種:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對象。
  • 方法區(qū)中類靜態(tài)屬性引用的對象。
  • 方法區(qū)中常量引用的對象。
  • 本地方法棧中JNI(即一般說的Native方法)引用的對象。
  • 2.垃圾收集算法

    垃圾收集算法分為如下:

    1.標(biāo)記-清除算法

    “標(biāo)記-清除”(Mark-Sweep)算法,算法分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記出 所有需要回收的對象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對象
    缺點(diǎn):
    一個是效率問題,標(biāo)記和清除兩個過程的效率都不高;
    一個是空間問題,標(biāo)記清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片, 空間碎片太多可能會導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對象時,無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動作。

    2. 復(fù)制算法

    將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使 用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。
    現(xiàn)在的商業(yè)虛擬機(jī)都采用這種收集算法來回收新生代,是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當(dāng)回收時,將Eden和Survivor中還存活著的對象一次性地復(fù)制到另外一塊Survivor空間上,最后清理掉Eden和剛 才用過的Survivor空間。HotSpot虛擬機(jī)默認(rèn)Eden和Survivor的大小比例是8:1,也就是每次新生代中可用內(nèi)存空間為整個新生代容量 的90%(80%+10%),只有10%的內(nèi)存會被“浪費(fèi)”。

    3.標(biāo)記-整理算法

    復(fù)制收集算法在對象存活率較高時就要進(jìn)行較多的復(fù)制操作,效率將會變低。根據(jù)老年代的特點(diǎn),有人提出了另外一種“標(biāo)記-整理”(Mark-Compact)算法,標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后 續(xù)步驟不是直接對可回收對象進(jìn)行清理,而是讓所有存活的對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存,

    4. 分代收集算法

    當(dāng)前商業(yè)虛擬機(jī)的垃圾收集都采用“分代收集”(GenerationalCollection)算法,只是根據(jù)對象 存活周期的不同將內(nèi)存劃分為幾塊。一般是把Java堆分為新生代和老年代,這樣就可以根據(jù)各個年代的特點(diǎn)采用最適當(dāng)?shù)氖占?法。在新生代中,每次垃圾收集時都發(fā)現(xiàn)有大批對象死去,只有少量存活,那就選用復(fù)制算法,只需要付出少量存活對象的復(fù)制 成本就可以完成收集。而老年代中因?yàn)閷ο蟠婊盥矢摺]有額外空間對它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記—清理”或者“標(biāo)記— 整理”算法來進(jìn)行回收。

    3.新生代 老年代

    Java堆是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱做“GC堆”(Garbage Collected Heap”)。從內(nèi)存回收的角度來看,由于現(xiàn)在收集器基本都采用分代收集算法,所以Java堆中還可以細(xì)分為:

    • 新生代:有Eden空間、FromSurvivor空間、To Survivor空間等。從內(nèi)存分配的角度來看,線程共享的Java堆中可能劃分出多個線 程私有的分配緩沖區(qū)(Thread LocalAllocationBuffer,TLAB)
    • 老年代:主要存放大對象,需要大量連續(xù)空間的對象;如長字符串和數(shù)組;長期存活的對象直接進(jìn)入老年代,虛擬機(jī)給每個對象定義了一個對象年齡(Age)計(jì)數(shù)器。如果對象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor容納的話,將被移動到Survivor空間中,并且對象年齡設(shè)為1。對象在Survivor區(qū)中每“熬過”一次Minor GC,年齡就增加1歲,當(dāng)它的年齡增加到一定程度(默認(rèn)為15歲),就將會被晉升到老年代中。
      為了能更好地適應(yīng)不同程序的內(nèi)存狀況,虛擬機(jī)并不是永遠(yuǎn)地要求對象的年齡必須達(dá)到了MaxTenuringThreshold才能晉升老年 代,如果在Survivor空間中相同年齡所有對象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進(jìn)入 老年代,無須等到MaxTenuringThreshold中要求的年齡。

    4.什么時候GC回收對象?

    大多數(shù)情況下,對象在新生代Eden區(qū)中分配。當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時,虛擬機(jī)將發(fā)起一次Minor GC,當(dāng)存活的對象所需要的空間大于survivor空間時,會存入老年代中,當(dāng)老年代的空間滿了,會觸發(fā)Full GC。

    總結(jié)

    以上是生活随笔為你收集整理的垃圾收集机制原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。