国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
什麼是垃圾回收
1. 引用計數(shù)器" >1. 引用計數(shù)器
首頁 Java Java入門 jvm的垃圾回收機制是什麼

jvm的垃圾回收機制是什麼

Feb 01, 2023 pm 02:02 PM
java jvm

jvm的垃圾回收機制是GC(Garbage Collection),也叫垃圾收集器。 GC基本原理:將記憶體中不再被使用的物件回收;GC中用於回收的方法稱為收集器,由於GC需要消耗一些資源和時間,Java在對物件的生命週期特徵進行分析後,按照新生代、老年代的方式來對物件進行收集,以盡可能的縮短GC對應(yīng)用造成的暫停。

jvm的垃圾回收機制是什麼

本教學操作環(huán)境:windows7系統(tǒng)、java8版、DELL G3電腦。

什麼是垃圾回收

java相較於c、c 語言的優(yōu)點之一是自備垃圾回收器,垃圾回收是指不定時去堆內(nèi)存中清理不可達物件。不可達到的物件不會馬上就會直接回收, 垃圾收集器在一個Java程式中的執(zhí)行是自動的,不能強制執(zhí)行,程式設(shè)計師唯一能做的就是透過呼叫System.gc 方法來建議執(zhí)行垃圾收集器,但其是否可以執(zhí)行,什麼時候執(zhí)行卻都是不可知的。這也是垃圾收集器的最主要的缺點。當然相對於它帶給程式設(shè)計師的巨大便利性而言,這個缺點是瑕不掩瑜的。

為什麼需要垃圾回收

如果不進行垃圾回收,記憶體遲早都會被消耗空,因為我們在不斷的分配記憶體空間而不進行回收。除非記憶體無限大,我們可以任性的分配而不回收,但事實並非如此。所以,垃圾回收是必須的。

jvm垃圾回收原理

在JVM運行時資料區(qū)存在一個堆區(qū), 堆是一個巨大的物件池。在這個物件池中管理著數(shù)量龐大的物件實例,而池中物件的參考層次,有的是很深的。一個被頻繁調(diào)用的接口,每秒生成對象的速度,是很大的,同時,對象之間的關(guān)係,形成了一張巨大的網(wǎng)。

Java 一直在營造一種無限記憶體的氛圍,但物件不能只增不減,所以需要垃圾回收;那 JVM 是如何判斷哪些物件應(yīng)該被回收?哪些應(yīng)該被保持?這就要用到JVM的垃圾回收機制了,也就是我們常說的GC(Garbage Collection),也叫垃圾收集器。

GC (Garbage Collection:即垃圾回收)的基本原理:將記憶體中不再被使用的物件進行回收,GC中用於回收的方法稱為收集器,由於GC需要消耗一些資源和時間,Java在對物件的生命週期特徵進行分析後,按照新生代、老年代的方式來對物件進行收集,以盡可能的縮短GC對應(yīng)用造成的暫停

● 對新生代的物件的收集稱為minor GC
● 對老年代的物件的收集稱為Full GC
● 程式中主動呼叫System.gc()強制執(zhí)行的GC為Full GC

#不同的物件參考類型, GC會採用不同的方法進行回收,JVM物件的參考分為了四種類型:
● 強引用:預設(shè)情況下,物件採用的均為強引用(這個物件的實例沒有其他物件引用,GC時才會被回收)
● 軟引用:軟引用是Java中提供的一種比較適合於快取場景的應(yīng)用(只有在記憶體不夠用的情況下才會被GC)
● 弱引用:在GC時一定會被GC回收
● 虛引用:由於虛引用只是用來得知物件是否被GC

## 物件被標記為垃圾方法

JVM的記憶體結(jié)構(gòu)包含五大區(qū)域:

程式計數(shù)器、虛擬機器堆疊、本機方法堆疊、堆疊區(qū)方法區(qū)。其中程式計數(shù)器、虛擬機器棧、本地方法棧3個區(qū)域隨線程而生、隨線程而滅,因此這幾個區(qū)域的記憶體分配和回收都具備確定性,就不需要過多考慮回收的問題,因為方法結(jié)束或執(zhí)行緒結(jié)束時,記憶體自然就跟著回收了。而Java堆區(qū)和方法區(qū)則不一樣,這部分記憶體的分配與回收是動態(tài)的,正是垃圾收集器所需關(guān)注的部分。

1. 引用計數(shù)器

參考計數(shù)是垃圾收集器中的早期策略。在這種方法中,堆中每個物件實例都有一個參考計數(shù)。當一個物件被建立時,就將該物件實例指派給一個變量,該變數(shù)計數(shù)設(shè)為1。當任何其它變數(shù)被賦值為這個物件的引用時,計數(shù)加1(a = b,則b引用的物件實例的計數(shù)器1),但當一個物件實例的某個引用超過了生命週期或被設(shè)定為一個新值時,物件實例的引用計數(shù)器減1。任何引用計數(shù)器為0的物件實例可以被當作垃圾收集。當一個物件實例被垃圾收集時,它所引用的任何物件實例的參考計數(shù)器會減1。

優(yōu)點: 引用計數(shù)收集器可以很快的執(zhí)行,交織在程式運作中。對程式需要不被長時間打斷的即時環(huán)境比較有利。
缺點: 無法偵測出循環(huán)引用。如父物件有一個子物件的引用,子物件反過來引用父物件。這樣,他們的引用計數(shù)永遠不可能是0。

jvm的垃圾回收機制是什麼

對上述程式碼透過引用計數(shù)法分析:

jvm的垃圾回收機制是什麼

jvm的垃圾回收機制是什麼

3-jvm的垃圾回收機制是什麼

2. 可達性分析

可達性演算法是目前主流的虛擬機都採用的演算法,程序把所有的引用關(guān)係看作一張圖,從一個節(jié)點GC Roots開始,尋找對應(yīng)的引用節(jié)點,找到這個節(jié)點以後,繼續(xù)尋找這個節(jié)點的引用節(jié)點,當所有的引用節(jié)點尋找完畢之後,剩餘的節(jié)點則被認為是沒有被引用到的節(jié)點,即無用的節(jié)點,無用的節(jié)點將會被判定為是可回收的物件。

在Java語言中,可作為GC Roots的物件包含以下幾種:
● 虛擬機器堆疊中所引用的物件(堆疊框架中的本機變數(shù)表);
● 方法區(qū)中類別靜態(tài)屬性所引用的物件;
● 方法區(qū)中常數(shù)引用的物件;
● 本地方法堆疊中JNI(Native方法)所引用的物件。

jvm的垃圾回收機制是什麼

可以得到物件實例1、2、4、6都具有物件可達性,也就是存活對象,不能被GC回收的物件。而隨想實例3、5雖然直接相連,但並沒有任何一個GC Roots與之相連,即GC Roots不可達對象,就會被GC回收的對象。

三、垃圾回收演算法

1. 標記-清除演算法

標記/清除演算法的基本想法就跟它的名字一樣,分為「標記」和「清除」兩個階段:首先標記所有需要回收的對象,在標記完成後統(tǒng)一回收所有被標記的對象。
標記階段:
標記的過程其實就是前面介紹的可達性分析演算法的過程,遍歷所有的GC Roots 對象,對從GCRoots 物件可達的物件都打上一個標識,一般是在物件的header 中,將其記錄為可達物件。
清除階段:
清除的過程是對堆記憶體進行遍歷,如果發(fā)現(xiàn)某個物件沒有被標記為可達物件(透過讀取物件header 訊息),則將其回收。

jvm的垃圾回收機制是什麼

上圖是標記/清除演算法的示意圖,在標記階段,從對象GC Root 1 可以存取B 對象,從B 對象又可以存取E 對象,因此從GC Root 1 到B、E 都是可達的,同理,物件F、G、J、K 都是可達物件;到了清除階段,所有不可達物件都會被回收。
在垃圾收集器進行GC 時,必須停止所有Java 執(zhí)行緒(也稱為"Stop The World"),原因是在標記階段進行可達性分析時,不可以出現(xiàn)分析過程中物件引用關(guān)係還在不斷變化的情況,否則的話可達性分析結(jié)果的準確性就無法得到保證。在等待標記清除結(jié)束後,應(yīng)用程式執(zhí)行緒才會恢復運作。

標記/清除演算法缺點:
效率問題
標記和清除兩個階段的效率都不高,因為這兩個階段都需要遍歷內(nèi)存中的對象,很多時候內(nèi)存中的對象實例數(shù)量是非常龐大的,這無疑很耗費時間,而且GC 時需要停止應(yīng)用程序,這會導致非常差的用戶體驗。
空間問題
標記清除之後會產(chǎn)生大量不連續(xù)的記憶體碎片(從上圖可以看出),記憶體空間碎片太多可能會導致以後在程式運行過程中需要分配較大物件時,無法找到足夠的連續(xù)記憶體而不得不提前觸發(fā)另一次垃圾回收動作。

2. 複製演算法

複製演算法是將可用記憶體依容量分割成大小相等的兩塊,每次使用其中的一塊。當這一塊的記憶體用完了,就將還存活的物件複製到另一塊記憶體上,然後把這一塊記憶體所有的物件一次清理掉
jvm的垃圾回收機制是什麼

#

複製演算法每次都是對整個半?yún)^(qū)進行內(nèi)存回收,這樣就減少了標記對象遍歷的時間,在清除使用區(qū)域?qū)ο髸r,不用進行遍歷,直接清空整個區(qū)域內(nèi)存,而且在將存活對象複製到保留區(qū)域時也是按位址順序儲存的,這樣就解決了記憶體碎片的問題,在分配物件記憶體時不用考慮記憶體碎片等複雜問題,只需要按順序分配記憶體即可。

複製演算法缺點:
複製演算法簡單高效,優(yōu)化了標記清除演算法的效率低、記憶體碎片多問題,存在缺點:
● 將記憶體縮小為原來的一半,浪費了一半的記憶體空間,代價太高;
● 如果物件的存活率很高,極端一點的情況假設(shè)物件存活率為100%,那麼我們需要將所有存活的物件複製一遍,耗費的時間代價也是不可忽視的。

3. 標記-整理演算法

標記-整理演算法演算法與標記/清除演算法很像,事實上,標記/整理演算法的標記過程任然與標記/清除演算法一樣,但後續(xù)步驟不是直接對可回收物件進行回收,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊線以外的記憶體。
jvm的垃圾回收機制是什麼

可以看到,回收後可回收物件被清理掉了,存活的物件按規(guī)則排列存放在記憶體中。這樣一來,當我們給新物件分配記憶體時,jvm 只需要持有記憶體的起始位址即可。標記/整理演算法彌補了標記/清除演算法存在記憶體碎片的問題消除了複製演算法記憶體減半的高額代價,可謂一舉兩得。

標記/整理缺點:
● 效率不高:不僅要標記存活對象,還要整理所有存活對象的參考位址,在效率上不如複製演算法。

4. 分代回收演算法

分代收集演算法的想法是按物件的存活週期不同將記憶體劃分為幾塊一般是把Java 堆分為新生代和老年代(還有一個永久代,是HotSpot 特有的實現(xiàn),其他的虛擬機實現(xiàn)沒有這一概念,永久代的收集效果很差,一般很少對永久代進行垃圾回收),這樣就可以根據(jù)各個年代的特徵採用最適合的收集演算法。

特色:
新生代:朝生夕滅,存活時間很短。採用複製演算法來收集
老年代:經(jīng)過多次 Minor GC 而存活下來,存活週期長。採用標記/清除演算法或標記/整理演算法收集老年代

新生代中每次垃圾回收都發(fā)現(xiàn)有大量的物件死去,只有少量存活,因此採用複製演算法回收新生代,只需要付出少量物件的複製成本就可以完成收集;
老年代中物件的存活率高,不適合採用複製演算法,而且如果老年代採用複製演算法,它是沒有額外的空間進行分配擔保的,因此必須使用標記/清理演算法或標記/整理演算法來進行回收。

jvm的垃圾回收機制是什麼

新生代中的物件“朝生夕死”,每次GC時都會有大量物件死去,少量存活,使用複製演算法。新生代又分為Eden區(qū)和Survivor區(qū)(Survivor from、Survivor to),大小比例預設(shè)為8:1:1。
老年代中的物件因為物件存活率高、沒有額外空間進行分配擔保,就使用標記-清除或標記-整理演算法。
新產(chǎn)生的物件優(yōu)先進去Eden區(qū),當Eden區(qū)滿了之後再使用Survivor from,當Survivor from 也滿了之後就進行Minor GC(新生代GC),將Eden和Survivor from中存活的物件copy進入Survivor to,然後清空Eden和Survivor from,這個時候原來的Survivor from成了新的Survivor to,原來的Survivor to成了新的Survivor from。複製的時候,如果Survivor to 無法容納全部存活的對象,則根據(jù)老年代的分配擔保(類似於銀行的貸款擔保)將對象copy進去老年代,如果老年代也無法容納,則進行Full GC(老年代GC)。
大物件直接進入老年代:JVM中有個參數(shù)配置
-XX:PretenureSizeThreshold,令大於這個設(shè)定值的物件直接進入舊年代,目的是為了避免在Eden和Survivor區(qū)之間發(fā)生大量的記憶體複製。
長期存活的物件進入老年代:JVM為每個物件定義一個物件年齡計數(shù)器,如果物件在Eden出生並經(jīng)過第一次Minor GC後仍然存活,並且能被Survivor容納,將被移入Survivor並且年齡設(shè)定為1。沒撐過一次Minor GC,年齡就加1,當他的年齡到一定程度(預設(shè)為15歲,可以透過XX:MaxTenuringThreshold來設(shè)定),就會移入老年代。但JVM並不是永遠要求年齡必須達到最大年齡才會晉升老年代,如果Survivor 空間中相同年齡(如年齡為x)所有物件大小的總和大於Survivor的一半,年齡大於等於x的所有物件直接進入老年代,無需等到最大年齡要求。

分代回收:

我們從一個object1來說明其在分代垃圾回收演算法中的回收軌跡。

1、object1新建,出生於新生代的Eden區(qū)域。
jvm的垃圾回收機制是什麼
2、minor GC,object1 仍存活,移動到From suvivor空間,此時仍在新生代。

jvm的垃圾回收機制是什麼

3、minor GC,object1 仍然存活,此時會透過複製演算法,將object1移到ToSuv區(qū)域,此時object1的年齡age 1。
jvm的垃圾回收機制是什麼
4、minor GC,object1 仍然存活,此時survivor中和object1同齡的物件並沒有達到survivor的一半,所以此時透過複製演算法,將fromSuv和Tosuv 區(qū)域進行互換,存活的物件被移到了Tosuv。
jvm的垃圾回收機制是什麼
5、minor GC,object1 仍然存活,此時survivor中和object1同齡的對像已經(jīng)達到survivor的一半以上(toSuv的區(qū)域已經(jīng)滿了),object1被移動到了老年代區(qū)域。
jvm的垃圾回收機制是什麼
6、object1存活一段時間後,發(fā)現(xiàn)此時object1不可達GcRoots,而且此時老年代空間比率已經(jīng)超過了閾值,觸發(fā)了majorGC(也可以認為是fullGC,但具體需要垃圾收集器來聯(lián)繫),此時object1被回收了。 fullGC會觸發(fā) stop the world。
jvm的垃圾回收機制是什麼
在以上的新生代中,我們有提到對象的age,對象存活於survivor狀態(tài)下,不會立即晉升為老年代對象,以避免給老年代造成過大的影響,它們必須要滿足以下條件才可以晉升:
1、minor gc 之後,存活於survivor 區(qū)域的對象的age會1,當超過(默認)15的時候,轉(zhuǎn)移到老年代。
2.動態(tài)對象,如果survivor空間中相同年齡所有的對像大小的綜合和大於survivor空間的一半,年級大於或等於該年紀的對象就可以直接進入老年代。

以上是jvm的垃圾回收機制是什麼的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔相應(yīng)的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在Java的地圖上迭代? 如何在Java的地圖上迭代? Jul 13, 2025 am 02:54 AM

遍歷Java中的Map有三種常用方法:1.使用entrySet同時獲取鍵和值,適用於大多數(shù)場景;2.使用keySet或values分別遍歷鍵或值;3.使用Java8的forEach簡化代碼結(jié)構(gòu)。 entrySet返回包含所有鍵值對的Set集合,每次循環(huán)獲取Map.Entry對象,適合頻繁訪問鍵和值的情況;若只需鍵或值,可分別調(diào)用keySet()或values(),也可在遍歷鍵時通過map.get(key)獲取值;Java8中可通過Lambda表達式使用forEach((key,value)-&gt

Java可選示例 Java可選示例 Jul 12, 2025 am 02:55 AM

Optional能清晰表達意圖並減少null判斷的代碼噪音。 1.Optional.ofNullable是處理可能為null對象的常用方式,如從map中取值時可結(jié)合orElse提供默認值,邏輯更清晰簡潔;2.通過鍊式調(diào)用map實現(xiàn)嵌套取值,安全地避免NPE,任一環(huán)節(jié)為null則自動終止並返回默認值;3.filter可用於條件篩選,滿足條件才繼續(xù)執(zhí)行後續(xù)操作,否則直接跳到o??rElse,適合輕量級業(yè)務(wù)判斷;4.不建議過度使用Optional,如基本類型或簡單邏輯中其反而增加複雜度,部分場景直接返回nu

Java中的可比較與比較器 Java中的可比較與比較器 Jul 13, 2025 am 02:31 AM

在Java中,Comparable用於類內(nèi)部定義默認排序規(guī)則,Comparator用於外部靈活定義多種排序邏輯。 1.Comparable是類自身實現(xiàn)的接口,通過重寫compareTo()方法定義自然順序,適用於類有固定、最常用的排序方式,如String或Integer。 2.Comparator是外部定義的函數(shù)式接口,通過compare()方法實現(xiàn),適合同一類需要多種排序方式、無法修改類源碼或排序邏輯經(jīng)常變化的情況。兩者區(qū)別在於Comparable只能定義一種排序邏輯且需修改類本身,而Compar

如何修復java.io.notserializable Exception? 如何修復java.io.notserializable Exception? Jul 12, 2025 am 03:07 AM

遇到j(luò)ava.io.NotSerializableException的核心解決方法是確保所有需序列化的類實現(xiàn)Serializable接口,並檢查嵌套對象的序列化支持。 1.給主類添加implementsSerializable;2.確保類中自定義字段對應(yīng)的類也實現(xiàn)Serializable;3.用transient標記不需要序列化的字段;4.檢查集合或嵌套對像中的非序列化類型;5.查看異常信息定位具體哪個類未實現(xiàn)接口;6.對無法修改的類考慮替換設(shè)計,如保存關(guān)鍵數(shù)據(jù)或使用可序列化的中間結(jié)構(gòu);7.考慮改

如何處理Java中的字符編碼問題? 如何處理Java中的字符編碼問題? Jul 13, 2025 am 02:46 AM

處理Java中的字符編碼問題,關(guān)鍵是在每一步都明確指定使用的編碼。 1.讀寫文本時始終指定編碼,使用InputStreamReader和OutputStreamWriter並傳入明確的字符集,避免依賴系統(tǒng)默認編碼。 2.在網(wǎng)絡(luò)邊界處理字符串時確保兩端一致,設(shè)置正確的Content-Type頭並用庫顯式指定編碼。 3.謹慎使用String.getBytes()和newString(byte[]),應(yīng)始終手動指定StandardCharsets.UTF_8以避免平臺差異導致的數(shù)據(jù)損壞??傊?,通過在每個階段

JavaScript數(shù)據(jù)類型:原始與參考 JavaScript數(shù)據(jù)類型:原始與參考 Jul 13, 2025 am 02:43 AM

JavaScript的數(shù)據(jù)類型分為原始類型和引用類型。原始類型包括string、number、boolean、null、undefined和symbol,其值不可變且賦值時復制副本,因此互不影響;引用類型如對象、數(shù)組和函數(shù)存儲的是內(nèi)存地址,指向同一對象的變量會相互影響。判斷類型可用typeof和instanceof,但需注意typeofnull的歷史問題。理解這兩類差異有助於編寫更穩(wěn)定可靠的代碼。

Java方法參考解釋了 Java方法參考解釋了 Jul 12, 2025 am 02:59 AM

方法引用是Java中一種簡化Lambda表達式的寫法,使代碼更簡潔。它不是新語法,而是Java8引入的Lambda表達式的一種快捷方式,適用於函數(shù)式接口的上下文。其核心在於將已有方法直接作為函數(shù)式接口的實現(xiàn)來使用。例如System.out::println等價於s->System.out.println(s)。方法引用主要有四種形式:1.靜態(tài)方法引用(ClassName::staticMethodName);2.實例方法引用(綁定到特定對象,instance::methodName);3.

Java中的'靜態(tài)”關(guān)鍵字是什麼? Java中的'靜態(tài)”關(guān)鍵字是什麼? Jul 13, 2025 am 02:51 AM

InJava,thestatickeywordmeansamemberbelongstotheclassitself,nottoinstances.Staticvariablesaresharedacrossallinstancesandaccessedwithoutobjectcreation,usefulforglobaltrackingorconstants.Staticmethodsoperateattheclasslevel,cannotaccessnon-staticmembers,

See all articles