1. 程式人生 > >何時GC的2種判定與3種GC演算法

何時GC的2種判定與3種GC演算法

1.在JDK1.2之前,使用的是引用計數器演算法,即當這個類被載入到記憶體之後,就會產生方法區,堆疊、程式計數
器等一系列資訊,當建立物件的時候,為這個物件在堆疊空間中分配物件,同時會產生一個引用計數器,同時引
用計數器+1,當有新的引用時,引用計數器繼續+1,而當其中一個引用銷燬時,引用計數器-1,當引用計數器減
為0的時候,標誌著這個物件已經沒有引用了,可以回收了!但是這樣會有一個問題:
當我們的程式碼出現這樣的情況時:
a)ObjA.obj=ObjB
b)ObjB.obj=ObjA
這樣的程式碼會產生如下引用情形objA指向objB,而ObjB又指向objA,這樣當其他所有的引用都消失了之後,objA
和objB還有一個相互的引用,也就是說兩個物件的引用計數器各為1,而實際上這兩個物件都已經沒有額外的引用,已經是垃圾了。


2.根搜尋演算法:

根搜尋演算法是從離散數學中的圖論引入的,程式把所有的引用關係看做一張圖,從一個節點GC Root開始,尋找對
應的引用節點,找到這個節點之後,繼續尋找這個節點的引用節點,當所有的引用節點尋找完畢之後,剩餘的節
點則被認為是沒有被飲用到的節點,即無用的節點。
目前Java中可作為GC Root的物件有:
1.虛擬機器棧中引用的物件(本地變量表)
2.方法區中靜態屬性引用的物件
3.方法區中常量引用的物件
4.本地方法棧中引用的物件(Native物件)。
java中存在的四種引用
(1)強引用:
只要引用存在,垃圾回收器永遠不會回收。
(2)軟引用
非必須引用,記憶體溢位之前進行回收,可以通過以下程式碼實現
Object obj=new Object();
SoftReference<Object> sf=new SoftRerence<Object>(obj);
obj=null;
sf.get();//有時會返回null

這時候sf是對obj的一個軟引用,通過sf.get()方法可以取到這個物件,當然這個物件被標記為需要回收的物件時,

則返回null;

軟引用主要用於使用者實現類似快取的功能,在記憶體不足的情況下直接通過軟引用取值,無需從繁忙的真實來源查
詢資料,提升速度;當記憶體不足時,自動刪除這部分快取資料,從真實的來源查詢這些資料。
(3)弱引用
第二次垃圾回收時回收,可以通過如下程式碼實現
Object obj=new Object();
WeakReference<Object> wf=new WeakReference<Object>(obj);
obj=null;
wf.get();//有時會返回null
wf.isEnQueued();//返回是否被垃圾回收器標記為即將回收的垃圾

弱引用是在第二次垃圾回收時回收,短時間內通過弱引用取對應的資料,可以取到,當執行過第二次垃圾回收時,

將返回null。弱引用主要用於監控物件是否已經被標記為即將回收的垃圾,可以通過弱引用的isEnQueues方法

返回物件是否被垃圾回收器標記。
(4)虛引用
垃圾回收時回收,無法通過引用取到物件值,可以通過如下程式碼實現
Object obj=new Object();
PhantomReference<Object> pf=new PhantomReference<Object>(obj);
obj=null;
pf.get();//永遠是返回null 
pf.isEnQueued();//返回從內從中已經刪除。
虛引用是每次垃圾回收的時候都會被回收,通過虛引用的get方法永遠獲取到的資料為null。

物件在記憶體中會被劃分為5塊區域,而每塊資料的回收比例是不同的(根據統計有):


方法區中主要存放類與類之間關係的資料,而這部分資料載入到記憶體之後,基本上是不會發生變更的,Java堆中的資料基本上是朝生夕死的,我們用完之後要馬上回收的,而Java棧和本地方法棧中的資料,因為有後進先出的原則,當我取下面的資料之前,必須要把棧頂的元素出棧,因此回收率可認為是100%,而程式計數器主要記錄程式執行的行號要跳轉的地址等一些資訊,這塊區域也是被認為是唯一一塊不會記憶體溢位的區域。方法區中的資料回收率比較低,而成本又比較高,一般認為“價效比”比較差的,所以SUN自己的虛擬機器HotSpot中是不可回收的!但是現在高效能分散式J2EE的系統中,我們大量用到了反射、動態代理等這些類頻繁的呼叫自定義類載入器,都需要動態的載入和解除安裝了,以保證永久不會溢位,他們通過自定義的類載入器進行了各種操作,因此在實際的應用開發中,類也是經常被載入和解除安裝的,方法區也是會被回收的!但是方法區中的回收條件非常苛刻,只有同時滿足以下三個條件才會被回收:
1.所有例項被回收
2.載入該類的ClassLoader被回收
3.Class物件無法通過任何途徑訪問(包括 反射)

垃圾回收演算法
標記-清除演算法(Mark-Sweep)

從根節點開始標記所有可達物件,其餘沒有標記的即為垃圾物件,執行清除。但回收後的空間是不連續的。


標記-清除演算法採用從根集合進行掃描,對存活的物件標記,標記完畢後,在掃描整個空間中未被標記的物件,進
行回收。
標記-清除演算法不需要進行物件的移動,並且僅對不存活的物件進行處理,在存活物件比較多的情況下極為高效,
但由於標記-清除演算法直接回收不存活的物件,因此會造成記憶體碎片。

複製演算法


複製演算法採用從根集合掃描,並將存活物件複製到一塊新的,沒有使用過的空間中,這種演算法當控制元件存活的物件
比較少時,極為高效,但是帶來的成本是需要一塊記憶體交換空間進行物件的移動。也就是s0,s1等空間。

標記-整理法


標記-整理演算法採用標記-清除演算法一樣的方式進行物件的標記,但在清除時,在回收不存活的物件佔用的空間後,

會將所有的存活物件網左端空閒空間移動,並更新相應的指標。標記-整理演算法是在標記-清除演算法的基礎上,

又進行了物件的移動,因此成本更高,但是卻解決了記憶體碎片的問題。

兩個最基本的Java垃圾回收演算法:複製演算法和標記清理演算法

常用的演算法

         複製演算法:兩個區域A和B,初始物件在A,繼續存活的物件被轉到B。此為新生代最為常用的演算法

         標記清理:一塊區域,標記要回收的物件,然後回收,一定會出現碎片,那麼一定會出現碎片,那麼引匯出標記-整理演算法

多了碎片整理,整理出更大的記憶體方更大的物件。

新生代和年老代

新生代:初始物件,生命週期短的         永久代:長時間存在的物件 

整個Java的垃圾回收是新生代和年老代的協作,這種叫做分代回收

PS:Serial New收集器是針對新生代的收集器,採用的是標記整理

         Parallel New新生代採用複製演算法,老年代採用標記整理

         Parallel Scavenge收集器,針對新生代,採用複製收集演算法

         Serial Old,新生代採用複製,老年代採用標記清理

Parallel Old,針對老年代,標記整理

CMS收集器,基於標記整理

G1收集器:整體上是基於標記清理,區域性採用複製

綜上:新生代基本採用複製演算法,老年代採用標記整理演算法。cms採用標記清理。

相關推薦

何時GC的2判定3GC演算法

1.在JDK1.2之前,使用的是引用計數器演算法,即當這個類被載入到記憶體之後,就會產生方法區,堆疊、程式計數 器等一系列資訊,當建立物件的時候,為這個物件在堆疊空間中分配物件,同時會產生一個引用計數器,同時引 用計數器+1,當有新的引用時,引用計數器繼續+1,而當其中一個

【REACT NATIVE 系列教程之一】觸控事件的兩形式TOUCHABLE元件詳解

本文是RN(React Native)系列教程第一篇,當然也要給自己的群做個廣告:  React Native @Himi :126100395  剛建立的群,歡迎一起學習、討論、進步。本文主要講解兩點:1.   PanResponder:觸控事件,用以獲取使用者手指所在螢幕的座標(x,y)或觸發、或滑動、或

3.深入jvm核心-原理、診斷優化-4. GC演算法和種類

一、GC演算法和種類 GC的概念 GC演算法 引用計數法 標記清除 標記壓縮 複製演算法 可觸及性 Stop-The-World

JVM GC調優(3)-----GC演算法(部分摘自深入理解Java虛擬機器)

介紹幾種GC演算法的思想及其發展過程: 標記-清除 複製 標記-壓縮 分代收集演算法 GC演算法主要是用於堆死亡物件的清理的集中方式,他們各有優缺點,下面我們開始做介紹 標記清除演算法 原理解析 -最基礎的收集演算法是“標記-清除”( Mark-Swe

iOS中3正則表達式的使用比較

regular null 後來 ons sta ring 學習 obj rst 之前我在博文中介紹過iOS中自帶正則表達式的使用(傳送門),後來我發現其實iOS中有三種方式來實現正則表達式的匹配。現在將他們都記錄在這裏: 1.利用NSPredicate(謂詞)匹配

JS實現隨機顏色的3方法顏色格式的轉化

JS實現隨機顏色的3種方法與顏色格式的轉化   隨機顏色和顏色格式是我們在開發中經常要用到的一個小功能,網上相關的資料也很多,想著有必要總結一下自己的經驗。所以這篇文章主要介紹了JS實現隨機顏色的3種方法與顏色格式的轉化,需要的朋友可以參考借鑑,下面來一

solidity智慧合約[25]-轉賬的3方式比較

轉賬的3種方式 123 address.transfer()address.send()address.call.value().gas()() 轉賬transfer 12345678910 function tran

MySQL儲存過程中的3迴圈,儲存過程的基本語法,ORACLEMYSQL的儲存過程/函式的使用區別,退出儲存過程方法

  學無止境 部落格園   首頁   新隨筆   聯絡   訂閱  管理 隨筆-1968  評論-103  文章-4&

3篇 RabbitMQ的5模式例項

3.1 簡單模式Hello World 功能:一個生產者P傳送訊息到佇列Q,一個消費者C接收 生產者實現思路: 建立連線工廠ConnectionFactory,設定服務地址127.0.0.1,埠號5672,設定使用者名稱、密碼、virtual host,從連線工廠中獲取連

馳騁工作流引擎JFlowactiviti的對比之3基於狀態的模式

延遲選擇(Deferred Choice) 流程中某個點可以有多個分支進行選擇。不是基於簡單的資料或者決定就可以很明顯地作出選擇,而是會向系統或者執行環境提供多種可選擇的分支;但是又不同於AND-Split模式,延遲選擇只能選擇一個分支執行,一旦選擇了其中第一個分支,那麼其他分支就會被

推薦系統3主要演算法學習筆記總結

以下均為個人總結,“我認為”居多,歡迎指正,給菜鳥一個學習的機會。 音樂推薦與普通商品推薦的區別 1、消費歌代價小; 免費 2、物品重用率高;喜歡的歌會重複聽,褲子未必會重複買 3、上下文相關性更大;和使用者當前心情、工作環境相關更大 推薦系統的指標 precision

資料庫設計(表表之間的3關係)

表與表之間一般存在三種關係,即一對一,一對多,多對多關係。 下面分別就三種關係講解資料庫相關設計的思路和思考過程; (1)一對一關係 例如,下面的一張表,儲存了人的相關資訊,有男有女,要求查處所有的夫妻。 sql程式碼: CREATE TABLE

分治動態規劃(3揹包問題)

動態規劃、分治法和貪心法都是利用求解子問題,而後利用子問題求解更上層問題,最終獲得全域性解決方案的方法。但是三者的應用場景和性質卻存在著極大的不同: 1. 分治法 分治法的精髓: 分–將問題分解為規模更小的子問題; 治–將這些規模更小的子問題逐個擊破

二叉樹3遍歷演算法遞迴非遞迴實現詳解

一, 二叉樹先序遍歷的實現     遞迴實現 void PreOrderTraverse(BiTree T) { if( T ) { VisitF(T->data);//訪問根節點 PreOrderTra

大資料系列之分散式釋出訂閱訊息系統Kafka(四)KafkaFlume的3整合

前面我們已經介紹了Flume,現在我們將Kafka與Flume整合 先看一下Flume的結構組成:            我們可以發現,將Flume與Kafka進行整合無非3種情況,Flume作為生產者——Sink輸出到Kafka,Flume作為消費者——Source接

GC演算法精解(複製演算法標記/整理演算法) 目前的兩主流演算法,基於標記清除演算法而來

refer to  http://www.cnblogs.com/zuoxiaolong/p/jvm5.html 在說以下兩種演算法前,說說他們的進化源——標記清除  有什麼問題。  第二點尤甚 1、首先,它的缺點就是效率比較低(遞迴與全堆物件遍歷),而且在進行GC的時候

React-Native 原生的3互動通訊(Android)

前言 最近到新公司,採用React-Native開發App。在某些效能方面有問題或者模組特殊的開發情況,不可避免的需要我們原生開發(Android\IOS)給予前端開發支援。 在為前端書寫模組部分,不可避免的要接觸核心的通訊部分。 大致分為2種情況:

iOS中3正則表示式的使用比較

iOS中有三種方式來實現正則表示式的匹配。現在將他們都記錄在這裡: 1.利用NSPredicate(謂詞)匹配 例如匹配有效郵箱: NSString *email = @“[email protected]”; NSString *regex = @"[A-Z0-

java實現二叉樹的構建以及3遍歷方法

輸出 for () 如果 順序 bintree 參考 oca gpl 轉載自http://ocaicai.iteye.com/blog/1047397 大二下學期學習數據結構的時候用C介紹過二叉樹,但是當時熱衷於java就沒有怎麽鳥二叉樹,但是對二叉樹的構建及遍歷一

mysql ACID隔離級別歸納總結

重新 style 出現 等待 mic 復讀 級別 for 保存 關於數據庫的ACID特性已經有很多的介紹,這裏再重新歸納總結一下: A(atomicity)原子性:   即事務要麽全部做完,要麽全部不做,不會出現只做一部分的情形,如A給B轉帳,不會出現A的錢少了,