最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 垃圾回收機制詳解及實例代碼

 更新時間:2017年02月13日 14:50:18   作者:Java開發(fā)-擱淺  
這篇文章主要介紹了 Java 垃圾回收機制詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下

 Java 垃圾回收機制詳解

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

手動管理內(nèi)存

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

下面是用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;
}

可以看到,你很容易就會忘了釋放內(nèi)存。內(nèi)存泄露曾經(jīng)是個非常普遍的問題。你只能通過不斷地修復(fù)自己的代碼來與它們進行抗爭。因此,需要有一種更優(yōu)雅的方式來自動釋放無用內(nèi)存,以便減少人為錯誤的可能性。這種自動化過程又被稱為垃圾回收(簡稱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會自動地刪除底層對應(yīng)的vector。當然這只是個示例,因為也有讀者指出來了,這個在現(xiàn)實中是不太可能出現(xiàn)的,但作為演示是足夠了。

自動內(nèi)存管理

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

 引用計數(shù) 

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

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

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

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

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

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

標記刪除

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

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

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

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

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

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

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

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Java入門之集合框架詳解

    Java入門之集合框架詳解

    本文介紹了Java集合框架體系結(jié)構(gòu),包括List、Set和Map接口及其常用實現(xiàn)類,重點講解了ArrayList、LinkedList、HashSet、TreeSet和HashMap等類的使用方法,并詳細介紹了泛型的定義和作用,最后,還討論了集合的遍歷和并發(fā)修改異常處理
    2025-01-01
  • 使用Java 8中的Lambda表達式實現(xiàn)工廠模式

    使用Java 8中的Lambda表達式實現(xiàn)工廠模式

    這篇文章主要給大家介紹了使用Java 8中的Lambda表達式實現(xiàn)工廠模式的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-04-04
  • Spring IOC和DI實現(xiàn)原理及實例解析

    Spring IOC和DI實現(xiàn)原理及實例解析

    這篇文章主要介紹了Spring IOC和DI實現(xiàn)原理及實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • java如何動態(tài)的處理接口的返回數(shù)據(jù)

    java如何動態(tài)的處理接口的返回數(shù)據(jù)

    本文主要介紹了java如何動態(tài)的處理接口的返回數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • jpa實現(xiàn)多對多的屬性時查詢的兩種方法

    jpa實現(xiàn)多對多的屬性時查詢的兩種方法

    這篇文章主要介紹了jpa實現(xiàn)多對多的屬性時查詢的兩種方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java關(guān)于后端怎么去接收Date、LocalDateTime類型的參數(shù)詳解

    Java關(guān)于后端怎么去接收Date、LocalDateTime類型的參數(shù)詳解

    這篇文章主要介紹了java關(guān)于后端怎么去接收Date、LocalDateTime類型的參數(shù),文中有詳細的代碼流程,對我們學習或工作有一定的參考價值,需要的朋友可以參考下
    2023-06-06
  • Java如何將大文件切割成小文件

    Java如何將大文件切割成小文件

    這篇文章主要為大家詳細介紹了Java如何將大文件切割成小文件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明

    Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明

    這篇文章主要介紹了Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)

    Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)

    這篇文章主要為大家介紹了Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • SpringBoot整合FTP使用示例教程

    SpringBoot整合FTP使用示例教程

    這篇文章主要介紹了SpringBoot整合FTP使用示例教程,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08

最新評論

邵阳市| 宝清县| 江阴市| 瑞金市| 四川省| 安国市| 定远县| 郑州市| 苏尼特右旗| 昌吉市| 台南市| 海城市| 浪卡子县| 屏东市| 赤水市| 武宁县| 双峰县| 云阳县| 桃源县| 香港 | 华亭县| 云林县| 嘉祥县| 泸水县| 绥江县| 开封市| 宜君县| 股票| 兰州市| 应城市| 拜城县| 新丰县| 满城县| 呼和浩特市| 行唐县| 溆浦县| 茂名市| 古丈县| 梁山县| 鹿邑县| 武夷山市|