JVM垃圾回收器學習筆記01

JVM GC概述

垃圾回收器,簡稱GC,也可以說是內存回收器,垃圾回收是JVM中最核心的功能之一。垃圾回收器主要關注三個問題:

  • 哪些內存需要回收(JVM運行時數據區內哪些區域需要進行內存回收)
  • 什麼時候回收
  • 如何回收(用什麼方法回收)

Java開發者無須像C/C++開發者那樣關注於內存相關的細節(內存申請、回收等),是得益於JVM的內存自動回收技術。而瞭解JVM的內存回收有益於,排查內存泄漏、內存溢出等問題,以及當垃圾回收成爲高併發的瓶頸時對垃圾回收的實施必要的調節。雖然上述幾種問題在生產環境很難遇到,但是多瞭解垃圾回收相關技術也是有必要的。

哪些內存需要回收

Java內存運行時區域包括,程序計數器、虛擬機棧、本地方法棧、堆、方法區。
其中程序計數器、虛擬機棧、本地方法棧區域中數據隨着線程而生,隨線程而滅,這幾個區域的內存分配和回收都具備確定性(當方法結束或線程結束後就可以回收內存)。
Java堆和方法區的內存需要GC回收,因爲這兩個區域的內存不具備確定性,一個接口的多個實現類需要的內存可能會不一樣,一個方法所執行的不同條件分支所需要的內存也可能不一樣,只有處於運行期間,我們才能知道程序究竟會創建哪些對象,創建多少個對象,這部分內存的分配和回收是動態的。

什麼時候回收

Java堆中存放的所有對象實例,GC進行內存回收的首要條件是判斷哪些對象實例可以回收,可以認爲對象被判定爲“死亡”後,就會被回收調內存。

怎麼判定一個Java對象實例“死亡”?
一般有兩種方式:

  • 引用計數算法(存在明顯的缺陷,主流的JVM沒有采用此方法管理內存)
  • 可達性分析算法

可達性分析算法

通過一系列稱爲“GC Roots”的根對象作爲起始節點集,從這些節點開始,根據引用關係向下搜索,搜索過程所走過的路徑稱爲“引用鏈”(Reference Chain),如果某個對象到GCRoots間沒有任何引用鏈相連,或者用圖論的話來說就是從GC Roots到這個對象不可達時,則證明此對象是不可能再被使用的。

哪些對象可以作爲GC Roots對象?

即使在可達性分析算法中判定爲不可達的對象,也不是“非死不可”的,這時候它們暫時還處於“緩刑”階段,要真正宣告一個對象死亡,至少要經歷兩次標記過程。可以通過重載實現finalize方法實現逃逸,即下圖中最下面的是否重新引用的判斷塊中,重新被引用,但每個實例對象的finalize方法只會最多被系統調用執行一次。

實例被判定是否存活的過程圖

如何回收

後續繼續完善

參考

全文參考來自書籍<深入理解Java虛擬機:JVM高級特性與最佳實踐>第三章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章