首頁 web前端 js教程 淺析堆與垃圾回收機制

淺析堆與垃圾回收機制

Jul 03, 2020 am 09:20 AM
垃圾回收機制

這篇文章我們主要關注這些問題::Java程式執行完後,堆中的物件什麼時候會被回收?如何回收?

堆又叫做「GC堆,」由於現在收集器基本上都採用分代收集演算法,所以Java堆還可以細分為:新生代和老年代,比例是1:2;再細緻一點新生代內部又劃分為Eden區、Survivor區,比例為8:1。下圖顯示了堆的結構:

#物件在堆中記憶體的分配是有嚴格規定的,策略為:

  • 物件優先在新生代Eden區分配記憶體;

  • 大物件直接進老年代,主要是長字串和陣列這些需要大量連續記憶體空間的物件;

  • #長期存活的物件進入老年代。 Eden區記憶體不夠時,JVM發起一次MinorGC,物件的年齡加一,預設物件年齡到15時進入老年代;

  • 動態年齡判定。相同年齡所有物件大小的總和大於Survivor 空間的一半,大於等於該年齡的物件進入舊年代

新生代GC指Minor GC,在新生代的進行垃圾回收,頻繁且快速。老年代 GC(Major GC/Full GC)在老年代進行垃圾回收,通常伴隨著至少一次的minor gc。速度慢。 Full GC在以下幾種情況下都會被觸發:

  1. 老年代空間不足;

  2. 方法區空間不足;

  3. 呼叫System.gc(),建議JVM進行full gc;

  4. 長期存活的物件轉入老年代,空間不足;

  5. 沒有足夠的連續空間分配給大物件;

  6. 新生代垃圾回收存活的對象太多,S1放不下,老年代擔保空間不足,擔保空間指的是老年代最大可用的連續空間是否大於新生代所有物件總空間。

  堆裡面幾乎放了所有的對象,那我們怎麼知道這些物件是否還有用呢? JVM提供了兩種方法來判定:

  • #引用計數法:給物件加入一個引用計數器,每次被引用,計數器值加一,引用失效,計數器值減一,當引用數為0時,表示物件不存活。引用計數法無法解決循環引用問題,週志朋老師書裡面有詳細的例子,也是比較容易理解的。

  • 可達性分析法#:以」GC Roots「物件為起始點,就像是樹的根節點,向下搜索,搜尋走過的路徑稱為引用鏈,如果一個物件到GC Roots起始點沒有引用鏈,則此對像不可達,是需要被回收的。 GC Roots是指虛擬機器棧所引用的對象,本地方法棧所引用的對象,方法區靜態屬性所引用的對象,方法區常數引用的對象。

    上面提到了引用,物件的存活都和引用有關,引用型別又分為強引用,軟引用,弱引用,虛引用。
  • 強引用,new出來的對象,垃圾回收器絕不會回收它;
  • ################# ###軟引用,在系統將要發生OMM前會回收這些物件的記憶體;###################弱引用,垃圾收集器工作時只要發現,馬上回收;##################虛引用,形同虛設,任何時候都可能被回收。 ######

實際上可達性分析法判定的不可達物件不會馬上回收,物件真正被回收需要經過兩次標記。第一次標記就是被判定為不可達對象,然後進行一次篩選,篩選條件是此對象是否有必要執行finalize()方法。如果沒有重寫finalize()方法或finalize()方法已經被虛擬機器呼叫過,finalize()方法只會被系統呼叫一次。這兩種情況都是」沒有必要執行的「。如果有必要,這個物件會被放在F-Quene佇列中,由虛擬機器自動建立的低優先權的#Finalizer執行緒去執行finalize()方法。這段期間GC會對F-Quene中的物件進行第二次小規模標記,如果物件仍然沒有被引用,那就會被回收,沒有被篩選的物件不一定會被回收。

#我們已經知道物件什麼時候被回收了,那要如何回收呢?介紹四種最常用的垃圾回收演算法:

  • 標記-清除:先標記需清除的對象,統一回收----效率不高,會產生大量不連續的碎片;

  • 複製演算法:將記憶體分塊,每次只使用一塊,使用完後,將存活的物件複製到另一塊上;

  • 標記整理:先標記存活對象,然後讓所有存活對象向一端移動,直接清理端邊界以外的記憶體;

  • 分代演算法,堆分隊新生代和老年代,新生代每次收集都會有大量的物件死去,選擇複製演算法。老年代存活率比較高,且沒有額外空間進行分配擔保,選擇標記清除或標記整理演算法。

垃圾收集演算法是一種記憶體回收的思想,具體的實作是垃圾收集器。簡單介紹下常用的垃圾收集器:

  • serial序列收集器。單線程,垃圾回收的時候,必須暫停其他工作。新生複製,老年標記整理。簡單又有效率;

  • ParNew 收集器。 serial的多執行緒版本;

  • Parallel Scavenge 收集器,複製演算法的多執行緒收集器。注重吞吐量,cpu運作程式碼時間/cpu耗時總時間。新生複製,老年標記整理;

  • Serial Old 收集器,舊年代版本;

  • Parallel Old 收集器,Parallel Scavenge老年代版本;

  • #CMS 收集器,專注於最短時間停頓。並發收集器,垃圾收集線程與用戶線程(基本上)同時工作。標記清除演算法

關於垃圾收集器更多的細節可以閱讀週志朋老師的書。

推薦教學:《JS教學

以上是淺析堆與垃圾回收機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

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整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

一文聊聊php中的垃圾回收機制 一文聊聊php中的垃圾回收機制 Aug 26, 2022 am 10:48 AM

這篇文章帶大家深入了解php中的垃圾回收機制,希望對大家有幫助!

解密Go語言的記憶體管理與垃圾回收機制 解密Go語言的記憶體管理與垃圾回收機制 Nov 30, 2023 am 09:17 AM

Go語言是一門高效、安全、並發的程式語言,其中記憶體管理和垃圾回收機制的設計也是其獨特之處。本文將深入解密Go語言的記憶體管理與垃圾回收機制。一、記憶體管理在Go語言中,記憶體管理包括記憶體分配和記憶體釋放兩個面向。 1.1記憶體分配在Go語言中,我們透過內建函數new和make來進行記憶體分配。其中,new傳回指向新指派的零值的指針,而make則傳回指定型別及其長

Java 函數中記憶體釋放的常見問題是如何解決的? Java 函數中記憶體釋放的常見問題是如何解決的? May 02, 2024 am 09:57 AM

Java中記憶體管理涉及垃圾收集,但仍可能出現問題。常見問題包括記憶體洩漏和記憶體碎片。記憶體洩漏是由於物件持有不再需要的引用,可用透過避免循環引用、使用弱引用和限定變數範圍來解決。記憶體碎片是由於頻繁分配和釋放導致,可用透過使用記憶體池、大物件池和壓縮垃圾收集來解決。例如,使用弱引用可以處理記憶體洩漏問題,確保垃圾收集器在不再需要時回收物件。

深入理解PHP底層開發原理:記憶體管理與垃圾回收機制 深入理解PHP底層開發原理:記憶體管理與垃圾回收機制 Sep 10, 2023 pm 02:30 PM

深入理解PHP底層開發原理:記憶體管理與垃圾回收機制引言:PHP作為一種高階程式語言,廣泛應用於Web開發。許多開發者對PHP的語法和特性都比較熟悉,但對於PHP底層開發原理的理解可能相對較少。本文將深入探討PHP底層開發原理中的記憶體管理與垃圾回收機制,幫助讀者更能理解PHP的運作機制。一、PHP的記憶體管理記憶體分配與釋放PHP中的記憶體管理是由Zend引擎負責

深入淺析JS中的垃圾回收機制 深入淺析JS中的垃圾回收機制 Mar 02, 2023 pm 07:31 PM

基本型別存放在堆疊中,引用型別存放在堆中。 JavaScript 是在創建變數(對象,字串等)時自動進行了分配內存,並且在不使用它們時“自動”釋放。釋放的過程稱為垃圾回收。

深入解析Python中的垃圾回收機制 深入解析Python中的垃圾回收機制 Mar 29, 2018 pm 01:20 PM

由於Python的自動垃圾回收機制,在Python中創建物件時無須手動釋放。這對開發者非常友好,讓開發者無須關注低層記憶體管理。但如果對其垃圾回收機制不了解,很多時候寫出的Python程式碼會非常低效。

探索Go語言的記憶體管理特性與垃圾回收機制 探索Go語言的記憶體管理特性與垃圾回收機制 Jan 23, 2024 am 10:07 AM

探索Go語言的垃圾回收機制與記憶體管理特色引言:隨著網路的發展,開發者對於程式語言的要求也越來越高。 Go語言作為一種靜態類型、編譯型語言,自誕生之初就憑藉其高效的垃圾回收機制和記憶體管理特點備受關注。本文旨在深入探索Go語言的垃圾回收機制以及其記憶體管理的特點,透過具體的程式碼範例幫助讀者更好地理解和利用這些特性。一、垃圾回收機制1.1標記-掃描演算法Go語言的

探究:JVM垃圾回收機制的不同發展階段 探究:JVM垃圾回收機制的不同發展階段 Feb 23, 2024 pm 05:36 PM

深度剖析:JVM垃圾回收機制的多樣化演變,需要具體程式碼範例一、引言隨著電腦科學的發展,垃圾回收機制在JVM(Java虛擬機)中扮演著至關重要的角色。 JVM垃圾回收機制的多樣化演進是為了改善Java程式的效能和記憶體管理。本文將深入剖析JVM垃圾回收機制的具體演變,同時提供具體的程式碼範例來幫助讀者更好地理解。二、垃圾回收機制的基本原理在解釋JVM垃圾回收機制的

See all articles