何時GC的2種判定與3種GC演算法
器等一系列資訊,當建立物件的時候,為這個物件在堆疊空間中分配物件,同時會產生一個引用計數器,同時引
用計數器+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種判定與3種GC演算法
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種迴圈,儲存過程的基本語法,ORACLE與MYSQL的儲存過程/函式的使用區別,退出儲存過程方法
學無止境 部落格園 首頁 新隨筆 聯絡 訂閱 管理 隨筆-1968 評論-103 文章-4&
第3篇 RabbitMQ的5種模式與例項
3.1 簡單模式Hello World 功能:一個生產者P傳送訊息到佇列Q,一個消費者C接收 生產者實現思路: 建立連線工廠ConnectionFactory,設定服務地址127.0.0.1,埠號5672,設定使用者名稱、密碼、virtual host,從連線工廠中獲取連
馳騁工作流引擎JFlow與activiti的對比之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(四)Kafka與Flume的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的錢少了,