1. 程式人生 > >GC可達性分析回收演算法 解決迴圈引用問題 強引用弱引用

GC可達性分析回收演算法 解決迴圈引用問題 強引用弱引用

JVM有一個回收演算法是引用計數演算法,每當物件被引用一次,就+1,釋放一個引用就-1,當垃圾回收時,引用計數為0的物件就會被GC掉。但這個方法有個問題,就是無法解決迴圈引用的問題。

迴圈引用就是物件A引用了物件B,物件B引用了物件A,構成了一個引用環。彼此都沒發揮什麼作用,但卻不會被GC。為了解決這個問題,就有了可達性分析回收演算法。

可達性分析:

演算法中定義了幾個GC Root物件,這幾個root物件在GC時不會被JVM回收掉,然後通過這些物件像樹枝一樣向外延伸,被引用到的物件說明還存活使用,就不會被GC,沒有被這些root物件引用到的就會被GC掉。從而解決了迴圈引用問題。

Root物件

主要包括:

①系統類載入器(bootstrap)載入的類。

②JVM方法區中靜態屬性引用的物件。

③JVM常量池中引用的物件。

④JVM虛擬機器棧中引用的物件。

⑤JVM本地方法棧中引用的物件。

⑥活動著的執行緒。

官方解釋:

GC roots

The so-called GC (Garbage Collector) roots are objects special for garbage collector. Garbage collector collects those objects that are not GC roots and are not accessible by references from GC roots.

There are several kinds of GC roots. One object can belong to more than one kind of root. The root kinds are:

  • Class - class loaded by system class loader. Such classes can never be unloaded. They can hold objects via static fields. Please note that classes loaded by custom class loaders are not roots, unless corresponding instances of java.lang.Class
     happen to be roots of other kind(s).
  • Thread - live thread
  • Stack Local - local variable or parameter of Java method
  • JNI Local - local variable or parameter of JNI method
  • JNI Global - global JNI reference
  • Monitor Used - objects used as a monitor for synchronization
  • Held by JVM - objects held from garbage collection by JVM for its purposes. Actually the list of such objects depends on JVM implementation. Possible known cases are: the system class loader, a few important exception classes which the JVM knows about, a few pre-allocated objects for exception handling, and custom class loaders when they are in the process of loading classes. Unfortunately, JVM provides absolutely no additional detail for such objects. Thus it is up to the analyst to decide to which case a certain "Held by JVM" belongs

強引用:

強引用就是引用了通過new 的方式建立的物件。在root搜尋演算法的裡面,說的引用都指的是強引用關係。

Object obj = new Object();

obj這個變數引用了一個object物件,只有obj這個引用被釋放了,物件才會被GC。

比如

obj=null;  

這樣物件就會被釋放。

軟引用:

軟引用的物件只有在記憶體不足的時候才會被回收掉,如果GC時,記憶體充足,那麼軟引用型別不會被回收。

軟引用的作用是:軟引用可用來實現記憶體敏感的快取記憶體。如果記憶體充足,就可以一直把快取放在記憶體中,加快資料訪問速度。如果記憶體不足了,快取就會被回收掉。

Object obj = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj);

弱引用:

弱引用只會生存很短的時間,在第一次經歷GC時,無論記憶體是否充足,都會被回收掉。

弱引用的作用就是:如果一個物件是偶爾的使用,並且希望在使用時隨時就能獲取到,但又不想影響此物件的垃圾收集,那麼就可以將物件修飾為為弱引用型別。弱引用還可以用於監控物件是否已經被垃圾回收器標記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回物件是否被垃圾回收器標記。還有一種情況:當你想引用一個物件,但是這個物件有自己的生命週期,你不想介入這個物件的生命週期,這時候就可以用弱引用。

Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference(obj);

虛引用:

虛引用就是假的引用,如果一個物件與虛引用關聯, 則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。虛引用必須配合引用佇列使用。

虛引用的作用:因為虛引用必須和引用佇列關聯使用,當垃圾回收器準備回收一個物件時, 如果發現它還有虛引用,就會把這個虛引用加入到與之關聯的引用佇列中。所以程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。 如果程式發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。

Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<Object> pf = new PhantomReference<Object>(obj,queue);

相關推薦

GC分析回收演算法 解決迴圈引用問題 引用引用

JVM有一個回收演算法是引用計數演算法,每當物件被引用一次,就+1,釋放一個引用就-1,當垃圾回收時,引用計數為0的物件就會被GC掉。但這個方法有個問題,就是無法解決迴圈引用的問題。 迴圈引用就是物件A引用了物件B,物件B引用了物件A,構成了一個引用環。彼此都沒發揮什麼作用

GC 分析演算法

在主流的商用程式語言的主要實現中,都是稱通過可達性分析(Reachability Analysis)來判定物件是否存活的,這個演算法的基本思路就是通過一系列的稱為“GC Roots“的物件作為起始點,從這些節點開始向下搜尋,搜尋所走過的路程成為引用鏈(Reference Chain),當一個物件

Java記憶體回收分析演算法

Java記憶體回收時的可達性分析演算法 也稱為傳遞跟蹤演算法; Java中,是通過可達性分析演算法來判斷物件是否存活的。 1:演算法的思路 通過一系列的“GC Roots”物件作為起點,開始向下搜尋 搜尋所走過的路徑稱為引用鏈; 當一個物件到GC Roots沒有

JVM分析演算法-判斷回收的物件

一JVM判斷哪些物件需要回收判斷物件是否需要回收,主要依據是該物件是否被其它地方引用。而判斷該物件是否被其它地方引用,主要有兩種演算法來實現。1、引用計數演算法該演算法的實現原理是:給物件一個引用計數器,每當有一個地方引用它時,計數器值就加1,當引用計數器失效時,計數器的值就

jvm原理四:利用分析演算法GC怎麼判斷物件生存還是死亡,經過了幾次過濾,每次都做了什麼

經歷了2次標記過程,即2次過濾過程。第一次:如果物件在進行可達性分析後發現沒有GC Roots相連線的引用鏈,那它將會被第一次標記並且進行一次篩選,篩選的條件是此物件是否有必要執行finalize()方

JAVA垃圾回收-分析演算法

在java中是通過引用來和物件進行關聯的,也就是說如果要操作物件,必須通過引用來進行。那麼很顯然一個簡單的辦法就是通過引用計數來判斷一個物件是否可以被回收。不失一般性,如果一個物件沒有任何引用與之關聯,則說明該物件基本不太可能在其他地方被使用到,那麼這個物件就成為可被回收的物

JVM 中判斷物件是否 “存活” 的演算法 —— 分析演算法

在堆中,幾乎存放著所有的物件例項,那麼回收這些物件例項時,我們需要判斷哪些物件是 “已死” 可以回收的,哪些物件是 “存活” 不需要回收的,下面就來介紹一下 JVM 中如何判斷上述問題的。 基本思路 通過一系列的稱為“GC Roots”的物件作為起始點,從這些節點開

Java虛擬機器判斷物件存活的兩種方案:引用計數法與分析演算法

java堆和方法區主要存放各種型別的物件(方法區中也儲存一些靜態變數和全域性常量等資訊),那麼我們在使用GC對其進行回收的時候首先要考慮的就是如何判斷一個物件是否應該被回收。也就是要判斷一個物件是否還有其他的引用或關聯使得這個物件處於存活的狀態。我們需要將不在存活狀態的所有物

JVM----判斷物件是否存活 : 引用計數演算法OR分析演算法?

本篇來自周志明的<<深入理解java虛擬機器>> 在堆裡面存放著Java世界中幾乎所有的物件例項,垃圾收集器在對堆進行回收前,第一件事情就是要確定這些物件之中哪些還“存活”著 ,哪些已經“死去”(即不可能再被任何途徑使用的物件)。 引用計數演算法 很多教科書判斷物

JVM——引用計數演算法分析演算法

前幾篇部落格我們一起認識了JVM的記憶體模型(程式計數器、虛擬機器棧、本地方法棧、方法區與堆),瞭解了它們的記憶體結構與分配,同時也略帶提到關於記憶體的回收。 JVM——記憶體模型(一):程式計數器 JVM——記憶體模型(二):虛擬機器棧與本地方法棧 JVM——記憶體模型(三):堆與方法

深入理解JVM——引用計數法和分析演算法(理解)

引言JVM中的堆和方法區主要用來存放物件(方法區中也儲存了一些靜態變數和全域性變數等資訊),那麼我們要使用GC演算法對其進行回收時首先要考慮的就是該物件是否應該被回收。即判斷該物件是否還有其他的引用或者

判斷物件存活:分析演算法

判斷物件存活,常用的方式是引用計數器:每當物件被一個地方引用,計數器便+1;當引用失效時,計數器-1。當物件的計數器為0時,該物件便是一個不被使用的物件,即“死亡”。引用計數器實現簡單,效率高。然而難以解決物件之間相互迴圈引用的問題(兩個失效物件相互儲存了對方的指標)。故JV

分析演算法

在Java語言中,可作為GC Roots的物件包括下面幾種:   a) 虛擬

JVM中垃圾回收機制如何判斷是否死亡?詳解引用計數法和分析

> 因為熱愛,所以堅持。 > 文章下方有本文參考電子書和視訊的**下載地址**哦~ 這節我們主要講垃圾收集的一些基本概念,先了解垃圾收集是什麼、然後觸發條件是什麼、最後虛擬機器如何判斷物件是否死亡。 ### 一、前言   我們都知道Java和C++有一個非常大的區別就是Java有自動的垃圾回收

分析算法-確定那些對象是垃圾(轉)

article ima -1 ability rdquo 靜態 roots 關聯 csdn 在主流的商用程序語言(Java、C#,甚至包括前面提到的古老的Lisp)的主流實現中,都是稱通過可達性分析(Reachability Analysis)來判定對象是否存活的。這個算法

懶癌晚期學圖論的時候自己用C語言寫了個求矩陣的演算法~

可達性矩陣演算法~ 直接上程式碼 #include <iostream> #include <cstring> using namespace std; #define n 5 void print(int a[n][n]); void print1(int a[n][n]); v

java 物件存活分析——引用計數法&分析

java虛擬機器總共分為五個區域,其中三個是執行緒私有:程式計數器,虛擬機器棧,本地方法棧,兩個是執行緒共享:堆,方法區。執行緒私有的區域等到執行緒結束時(棧幀出棧時)會自動被釋放,空間比較容易清理。而執行緒共享的java堆和方法區中的空間較大而且沒有執行緒的回

簡單分析

C Roots的物件作為起始點,從這些節點開始向下搜尋,搜尋所走過的路徑稱為引用鏈,當一個物件到GC Roots沒有任何引用鏈相連

面試官:你說你熟悉jvm?那你講一下併發的分析

這是why技術的第35篇原創文章 上面這張圖是我還是北漂的時候,在鼓樓附近的衚衕裡面拍的。 那天剛剛下完雨,路過這個地方的時候,一瞬間就被這五顏六色的門板和自行車給吸引了,於是拍下了這張圖片。看到這張圖片的時候我就很開心,多鮮活、多舒服的畫面呀。 以後的文章裡面我的第一張配圖都用自己隨時拍下的照片吧。分享

java jvm GC的基石 演算法

在jvm中 任何堆中物件 與GC root set不可達就會被gc回收。 那麼gc root set是什麼呢? 1.虛擬機器棧(棧幀中的本地變量表)中引用的物件。 2.方法區中類靜態屬性引用的物件。 3.方法區中常量引用的物件。 4.本地方法棧中JNI引用的物件。 如果物件