欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

GC參考手冊jvm垃圾回收詳解

 更新時間:2022年01月25日 14:38:49   作者:金色夢想  
顧名思義,垃圾收集(Garbage?Collection)的意思就是?——?找到垃圾并進行清理。但現(xiàn)有的垃圾收集實現(xiàn)卻恰恰相反:?垃圾收集器跟蹤所有正在使用的對象,并把其余部分當做垃圾。記住這一點以后,?我們再深入講解內(nèi)存自動回收的原理,探究?JVM?中垃圾收集的具體實現(xiàn)

1,什么是垃圾回收?

顧名思義,垃圾收集(Garbage Collection)的意思就是 —— 找到垃圾并進行清理。但現(xiàn)有的垃圾收集實現(xiàn)卻恰恰相反: 垃圾收集器跟蹤所有正在使用的對象,并把其余部分當做垃圾

我們不摳細節(jié), 先從基礎(chǔ)開始, 介紹垃圾收集的一般特征、核心概念以及實現(xiàn)算法。

2,手動內(nèi)存管理(Manual Memory Management)

當今的自動垃圾收集算法極為先進, 但我們先來看看什么是手動內(nèi)存管理。在那個時候, 如果要存儲共享數(shù)據(jù), 必須顯式地進行 內(nèi)存分配(allocate)和內(nèi)存釋放(free)。如果忘記釋放, 則對應(yīng)的那塊內(nèi)存不能再次使用。內(nèi)存一直被占著, 卻不再使用,這種情況就稱為內(nèi)存泄漏(memory leak)。

以下是用C語言來手動管理內(nèi)存的一個示例程序:

int send_request() {
    size_t n = read_size();
    int *elements = malloc(n * sizeof(int));

    if(read_elements(n, elements) < n) {
        // elements not freed!
        return -1;
    }

    // …

    free(elements)
    return 0;
}

可以看到,如果程序很長,或者結(jié)構(gòu)比較復雜, 很可能就會忘記釋放內(nèi)存。內(nèi)存泄漏曾經(jīng)是個非常普遍的問題, 而且只能通過修復代碼來解決。因此,業(yè)界迫切希望有一種更好的辦法,來自動回收不再使用的內(nèi)存,完全消除可能的人為錯誤。這種自動機制被稱為 垃圾收集(Garbage Collection,簡稱GC)。

智能指針(Smart Pointers)

第一代自動垃圾收集算法, 使用的是引用計數(shù)(reference counting)。針對每個對象, 只需要記住被引用的次數(shù), 當引用計數(shù)變?yōu)?時, 這個對象就可以被安全地回收(reclaimed)了。一個著名的示例是 C++ 的共享指針(shared pointers):

int send_request() {
    size_t n = read_size();
    vector<int> elements = vector<int>(n);

    if(read_elements(elements.size(), &elements[0]) < n) {
        return -1;
    }

    return 0;
}

shared_ptr 被用來跟蹤引用的數(shù)量。作為參數(shù)傳遞時這個數(shù)字加1, 在離開作用域時這個數(shù)字減1。當引用計數(shù)變?yōu)?時, shared_ptr 自動刪除底層的 vector。需要向讀者指出的是,這種方式在實際編程中并不常見, 此處僅用于演示。

int send_request() {
    size_t n = read_size();
    auto elements = make_shared<vector<int>>();

    // read elements

    store_in_cache(elements);

    // process elements further

    return 0;
}

現(xiàn)在,為了避免在下次調(diào)用函數(shù)時讀取元素,我們可能需要緩存它們。在這種情況下,當它超出范圍時銷毀向量不是一種選擇。因此,我們使用 shared_ptr。它跟蹤對它的引用數(shù)量。這個數(shù)字隨著你的傳遞而增加,隨著它離開范圍而減少。一旦引用數(shù)達到零,  shared_ptr 就會 自動刪除底層向量。

3,自動內(nèi)存管理(Automated Memory Management)

上面的C++代碼中,我們要顯式地聲明什么時候需要進行內(nèi)存管理。但不能讓所有的對象都具備這種特征呢? 那樣就太方便了, 開發(fā)者不再耗費腦細胞, 去考慮要在何處進行內(nèi)存清理。運行時環(huán)境會自動算出哪些內(nèi)存不再使用,并將其釋放。換句話說, 自動進行收集垃圾。第一款垃圾收集器是1959年為Lisp語言開發(fā)的, 此后 Lisp 的垃圾收集技術(shù)也一直處于業(yè)界領(lǐng)先水平。

引用計數(shù)(Reference Counting)

剛剛演示的C++共享指針方式, 可以應(yīng)用到所有對象。許多語言都采用這種方法, 包括 Perl、Python 和 PHP 等。下圖很好地展示了這種方式:

圖中綠色的云(GC ROOTS) 表示程序正在使用的對象。從技術(shù)上講, 這些可能是當前正在執(zhí)行的方法中的局部變量,或者是靜態(tài)變量一類。在某些編程語言中,可能叫法不太一樣,這里不必摳名詞。

藍色的圓圈表示可以引用到的對象, 里面的數(shù)字就是引用計數(shù)。然后, 灰色的圓圈是各個作用域都不再引用的對象?;疑膶ο蟊徽J為是垃圾, 隨時會被垃圾收集器清理。

看起來很棒, 是吧! 但這種方式有個大坑, 很容易被循環(huán)引用(detached cycle) 給搞死。任何作用域中都沒有引用指向這些對象,但由于循環(huán)引用, 導致引用計數(shù)一直大于零。如下圖所示:

看到了嗎? 紅色的對象實際上屬于垃圾。但由于引用計數(shù)的局限, 所以存在內(nèi)存泄漏。

當然也有一些辦法來應(yīng)對這種情況, 例如 “弱引用”(‘weak’ references), 或者使用另外的算法來排查循環(huán)引用等。前面提到的 Perl、Python 和PHP 等語言, 都使用了某些方式來解決循環(huán)引用問題, 但本文不對其進行討論。下面介紹JVM中使用的垃圾收集方法。

標記-清除(Mark and Sweep)

首先, JVM 明確定義了什么是對象的可達性(reachability)。我們前面所說的綠色云這種只能算是模糊的定義, JVM 中有一類很明確很具體的對象, 稱為 垃圾收集根元素(Garbage Collection Roots),包括:

  • 局部變量(Local variables)
  • 活動線程(Active threads)
  • 靜態(tài)域(Static fields)
  • JNI引用(JNI references)
  • 其他對象(稍后介紹 …)

JVM使用標記-清除算法(Mark and Sweep algorithm), 來跟蹤所有的可達對象(即存活對象), 確保所有不可達對象(non-reachable objects)占用的內(nèi)存都能被重用。其中包含兩步:

  • Marking(標記): 遍歷所有的可達對象,并在本地內(nèi)存(native)中分門別類記下。

  • Sweeping(清除): 這一步保證了,不可達對象所占用的內(nèi)存, 在之后進行內(nèi)存分配時可以重用。

JVM中包含了多種GC算法, 如Parallel Scavenge(并行清除), Parallel Mark+Copy(并行標記+復制) 以及 CMS, 他們在實現(xiàn)上略有不同, 但理論上都采用了以上兩個步驟。

標記清除算法最重要的優(yōu)勢, 就是不再因為循環(huán)引用而導致內(nèi)存泄露:

而不好的地方在于, 垃圾收集過程中, 需要暫停應(yīng)用程序的所有線程。假如不暫停,則對象間的引用關(guān)系會一直不停地發(fā)生變化, 那樣就沒法進行統(tǒng)計了。這種情況叫做 STW停頓(Stop The World pause, 全線暫停), 讓應(yīng)用程序暫時停止,讓JVM進行內(nèi)存清理工作。有很多原因會觸發(fā) STW停頓, 其中垃圾收集是最主要的因素。

在本手冊中,我們將介紹JVM中垃圾收集的實現(xiàn)原理,以及如何高效地利用GC。

以上就是GC參考手冊jvm垃圾回收詳解的詳細內(nèi)容,更多關(guān)于GC參考手冊jvm垃圾回收的資料請關(guān)注腳本之家其它相關(guān)文章!

原文鏈接:https://plumbr.io/handbook/what-is-garbage-collection

相關(guān)文章

  • Java中緩沖流的使用與性能提升(讓文件操作更高效)

    Java中緩沖流的使用與性能提升(讓文件操作更高效)

    本文通過實例代碼介紹了Java中緩沖流的概念、工作原理和性能提升,并提供了字節(jié)緩沖流和字符緩沖流的使用示例,緩沖流通過在內(nèi)存中創(chuàng)建緩沖區(qū),減少實際的I/O操作次數(shù),從而提升文件讀寫性能,結(jié)合實例代碼給大家講解的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Java SSM整合開發(fā)統(tǒng)一結(jié)果封裝詳解

    Java SSM整合開發(fā)統(tǒng)一結(jié)果封裝詳解

    這篇文章主要介紹了Java SSM整合開發(fā)實現(xiàn)統(tǒng)一結(jié)果封裝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 解決springboot 獲取form-data里的file文件的問題

    解決springboot 獲取form-data里的file文件的問題

    這篇文章主要介紹了解決springboot 獲取form-data里的file文件的問題的相關(guān)資料,這里提供了詳細的解決步驟,需要的朋友可以參考下
    2017-07-07
  • 詳解如何繼承Mybatis中Mapper.xml文件

    詳解如何繼承Mybatis中Mapper.xml文件

    這篇文章主要為大家介紹了詳解如何繼承Mybatis中Mapper.xml文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Java+EasyExcel實現(xiàn)文件上傳功能

    Java+EasyExcel實現(xiàn)文件上傳功能

    這篇文章主要為大家詳細介紹了如何通過Java和EasyExcel實現(xiàn)文件上傳功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-02-02
  • java8中的Collectors.groupingBy用法詳解

    java8中的Collectors.groupingBy用法詳解

    這篇文章主要介紹了java8中的Collectors.groupingBy用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Java文件讀寫詳解

    Java文件讀寫詳解

    在真實的應(yīng)用場景中,很多時候需要使用?Java?讀寫文件。比如說,讀取配置文件信息、讀取用戶輸入等。本篇文章將會詳細介紹?Java?文件讀寫的相關(guān)知識,其中包括:讀取文件、寫入文件、復制文件和刪除文件等操作,需要的朋友可以參考下
    2023-05-05
  • 基于Security實現(xiàn)OIDC單點登錄的詳細流程

    基于Security實現(xiàn)OIDC單點登錄的詳細流程

    本文主要是給大家介紹 OIDC 的核心概念以及如何通過對 Spring Security 的授權(quán)碼模式進行擴展來實現(xiàn) OIDC 的單點登錄。對Security實現(xiàn)OIDC單點登錄的詳細過程感興趣的朋友,一起看看吧
    2021-09-09
  • java程序中protobuf的基本用法示例

    java程序中protobuf的基本用法示例

    這篇文章主要給大家介紹了關(guān)于java程序中protobuf的基本用法,protobuf 與json相比具有 壓縮比高 、解壓縮速度更快的優(yōu)點,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • Java實現(xiàn)將Boolean轉(zhuǎn)為Json對象的方法

    Java實現(xiàn)將Boolean轉(zhuǎn)為Json對象的方法

    在Java中,將boolean值轉(zhuǎn)換為JSON對象通常涉及使用JSON庫,例如org.json或Gson,這里我們將使用org.json庫來進行詳細演示,這個庫提供了簡單且直觀的方法來創(chuàng)建和操作JSON對象,需要的朋友可以參考下
    2024-11-11

最新評論