成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 垃圾回收機制概念梳理

開發(fā) 后端
本文摘自我們幾周后即將出版的Garbage Collection Handbook一書的樣章。同時也讓你能熟悉下垃圾回收的基礎知識——這選自該書的第一章。

本文摘自我們幾周后即將出版的Garbage Collection Handbook一書的樣章。同時也讓你能熟悉下垃圾回收的基礎知識——這選自該書的***章。

乍一看,垃圾回收所做的事情應當恰如其名——查找并清除垃圾。事實上卻恰恰相反。垃圾回收會跟蹤所有仍在使用的對象,然后將剩余的對象標記為垃圾。牢記了這點之后,我們再來深入地了解下這個被稱為“垃圾回收”的自動化內存回收在JVM中到底是如何實現(xiàn)的。

手動管理內存

在介紹現(xiàn)代版的垃圾回收之前,我們先來簡單地回顧下需要手動地顯式分配及釋放內存的那些日子。如果你忘了去釋放內存,那么這塊內存就無法重用了。這塊內存被占有了卻沒被使用。這種場景被稱之為內存泄露

下面是用C寫的一個手動管理內存的簡單例子:

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;
}

可以看到,你很容易就會忘了釋放內存。內存泄露曾經(jīng)是個非常普遍的問題。你只能通過不斷地修復自己的代碼來與它們進行抗爭。因此,需要有一種更優(yōu)雅的方式來自動釋放無用內存,以便減少人為錯誤的可能性。這種自動化過程又被稱為垃圾回收(簡稱GC)。

智能指針

自動垃圾回收早期的一種實現(xiàn)便是引用計數(shù)。你知曉每一個對象被引用了幾次,當計數(shù)器歸0的時候,這個對象就可以被安全地回收掉了。C++的共享指針就是一個非常著名的例子:

int send_request() {
    size_t n = read_size();
    stared_ptr<vector<int>> elements 
              = make_shared<vector<int>&gt();

    if(read_elements(n, elements) < n) {
        return -1;
    }

    return 0;
}

我們使用的sharedptr會記錄這個對象被引用的次數(shù)。如果你將它傳遞給別人則計數(shù)加一,當它離開了作用域后便會減一。一旦這個計數(shù)為0,sharedptr會自動地刪除底層對應的vector。當然這只是個示例,因為也有讀者指出來了,這個在現(xiàn)實中是不太可能出現(xiàn)的,但作為演示是足夠了。

自動內存管理

在上面的C++代碼中,我們還得顯式地聲明我們需要使用內存管理。那如果所有的對象都采用這個機制會怎樣呢?那簡直就太方便了,這樣開發(fā)人員便無需 考慮清理內存的事情了。運行時會自動知曉哪些內存不再使用了,然后釋放掉它。也就是說,它自動地回收了這些垃圾。***代的垃圾回收器是1959年Lisp 引入的,這項技術迄今為止一直在不斷演進。

引用計數(shù)

剛才我們用C++的共享指針所演示的想法可以應用到所有的對象上來。許多語言比如說Perl, Python以及PHP,采用的都是這種方式。這個通過一張圖可以很容易說明:

 

綠色的云代表的是程序中仍在使用的對象。從技術層面上來說,這有點像是正在執(zhí)行的某個方法里面的局部變量,亦或是靜態(tài)變量之類的。不同編程語言的情況可能會不一樣,因此這并不是我們關注的重點。

藍色的圓圈代表的是內存中的對象,可以看到有多少對象引用了它們。灰色圓圈的對象是已經(jīng)沒有任何人引用的了。因此,它們屬于垃圾對象,可以被垃圾回收器清理掉。

看起來還不錯對吧?沒錯,不過這里存在著一個重大的缺陷。很容易會出現(xiàn)一些孤立的環(huán),它們中的對象都不在任何域內,但彼此卻互相引用導致引用數(shù)不為0。下面便是一個例子:

什么是垃圾回收

看到了吧,紅色部分其實就是應用程序不再使用的垃圾對象。由于引用計數(shù)的缺陷,因此會存在內存泄露。

有幾種方法可以解決這一問題,比如說使用特殊的“弱”引用,或者使用一個特殊的算法回收循環(huán)引用。之前提到的Perl,Python以及PHP等語言,都是使用類似的方法來回收循環(huán)引用的,不過這已經(jīng)超出本文講述的范圍了。我們準備詳細介紹下JVM所采用的方法。

標記刪除

首先,JVM對于對象可達性的定義要明確一些。它可不像前面那樣用綠色的云便含糊了事的,而是有著非常明確及具體的垃圾回收根對象(Garbage Collection Roots)的定義:

  • 局部變量
  • 活動線程
  • 靜態(tài)字段
  • JNI引用
  • 其它(后面將會討論到)

JVM通過標記刪除的算法來記錄所有可達(存活)對象,同時確保不可達對象的那些內存能夠被重用。這包含兩個步驟:

  • 標記是指遍歷所有可達對象,然后在本地內存中記錄這些對象的信息
  • 刪除會確保不可達對象的內存地址可以在下一次內存分配中使用。

JVM中的不同GC算法,比如說Parallel Scavenge,Parallel Mark+Copy, CMS都是這一算法的不同實現(xiàn),只是各階段略有不同而已,從概念上來講仍然是對應著上面所說的那兩個步驟。

這種實現(xiàn)最重要的就是不會再出現(xiàn)泄露的對象環(huán)了:

什么是垃圾回收

缺點就是應用程序的線程需要被暫停才能完成回收,如果引用一直在變的話你是無法進行計數(shù)的。這個應用程序被暫停以便JVM可以收拾家務的情況又被稱為Stop The World pause(STW)。這種暫停被觸發(fā)的可能性有很多,不過垃圾回收應該是最常見的一種。

 

責任編輯:王雪燕 來源: Java譯站
相關推薦

2009-06-23 14:15:00

Java垃圾回收

2011-07-04 16:48:56

JAVA垃圾回收機制GC

2011-06-28 12:39:34

Java垃圾回收

2010-09-25 15:33:19

JVM垃圾回收

2017-08-17 15:40:08

大數(shù)據(jù)Python垃圾回收機制

2017-03-03 09:26:48

PHP垃圾回收機制

2010-10-13 10:24:38

垃圾回收機制JVMJava

2021-11-05 15:23:20

JVM回收算法

2010-09-16 15:10:24

JVM垃圾回收機制

2021-05-27 21:47:12

Python垃圾回收

2010-09-25 15:26:12

JVM垃圾回收

2017-06-12 17:38:32

Python垃圾回收引用

2010-09-26 14:08:41

Java垃圾回收

2016-08-11 14:26:29

Java垃圾回收機制內存分配

2016-08-11 15:02:54

Java垃圾回收機制內存

2009-12-09 17:28:34

PHP垃圾回收機制

2021-12-07 08:01:33

Javascript 垃圾回收機制前端

2024-10-28 13:18:54

2021-02-26 05:24:35

Java垃圾回收

2016-08-11 14:49:34

Java垃圾回收機制異常
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产福利资源 | 婷婷色国产偷v国产偷v小说 | 日韩视频在线观看中文字幕 | 欧美女优在线观看 | 中文字幕在线视频精品 | 国产视频福利一区 | 蜜月va乱码一区二区三区 | 久久99蜜桃综合影院免费观看 | 欧美黑人狂野猛交老妇 | 欧美激情第一区 | 日韩三级电影一区二区 | 中文字幕精品一区二区三区精品 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 国产精品久久一区 | av黄色免费在线观看 | 日韩精品一区二区三区视频播放 | 成人免费视频 | 91免费在线看 | 欧美日韩在线观看视频 | 91人人爽 | 国产激情精品视频 | 国产精品一区二区三区在线 | 91免费看片 | 国产亚洲精品精品国产亚洲综合 | 一级免费毛片 | 久久精品一 | 国产精品免费大片 | 亚洲三区在线观看 | 嫩草视频网站 | 高清免费在线 | 国产精品波多野结衣 | 天天干成人网 | 日本色综合 | 欧美美女一区二区 | 久久最新精品视频 | 男女网站免费观看 | 国产精品欧美精品 | 国产精品久久久久久久久大全 | 欧美成人高清视频 | 国产情侣在线看 | 天天天天天天天干 |