《深入理解Java虛擬機》讀書筆記3--垃圾回收算法

轉載:http://blog.csdn.net/tjiyu/article/details/53983064

?

下面先來了解Java虛擬機垃圾回收的幾種常見算法:標記-清除算法、復制算法、標記-整理算法、分代收集算法、火車算法,介紹它們的算法思路,有什么優點和缺點,以及主要應用場景。

1、標記-清除算法

???????標記-清除(Mark-Sweep)算法是一種基礎的收集算法。

1、算法思路

???????"標記-清除"算法,分為兩個階段:

(A)、標記

??????首先標記出所有需要回收的對象;

???????標記過程如《Java虛擬機垃圾回收(一) 基礎》"2-4、判斷對象生存還是死亡"中所述--分為兩個標記過程(詳細請參考前文):

(1)、第一次標記

???????在可達性分析后發現對象到GC Roots沒有任何引用鏈相連時,被第一次標記;

???????并且進行一次篩選:此對象是否必要執行finalize()方法;

???????對有必要執行finalize()方法的對象,被放入F-Queue隊列中;????

(2)、第二次標記

???????GC將對F-Queue隊列中的對象進行第二次小規模標記;

???????在其finalize()方法中重新與引用鏈上任何一個對象建立關聯,第二次標記時會將其移出"即將回收"的集合;

???????對第一次被標記,且第二次還被標記(如果需要,但沒有移出"即將回收"的集合),就可以認為對象已死,可以進行回收

(B)、清除

??????兩次標記后,還在"即將回收"集合的對象將被統一回收;

???????執行過程如下圖:

2、優點

???????基于最基礎的可達性分析算法,它是最基礎的收集算法;

???????而后續的收集算法都是基于這種思路并對其不足進行改進得到的;

3、缺點

???????主要有兩個缺點:

(A)、效率問題

???????標記和清除兩個過程的效率都不高;

(B)、空間問題

???????標記清除后會產生大量不連續的內存碎片;

???????這會導致分配大內存對象時,無法找到足夠的連續內存;

???????從而需要提前觸發另一次垃圾收集動作;

4、應用場景

??????針對老年代的CMS收集器;

2、復制算法

???????"復制"(Copying)收集算法,為了解決標記-清除算法的效率問題;

1、算法思路

???????(A)、把內存劃分為大小相等的兩塊,每次只使用其中一塊;

???????(B)、當一塊內存用完了,就將還存活的對象復制到另一塊上(而后使用這一塊);

???????(C)、再把已使用過的那塊內存空間一次清理掉,而后重復步驟2;????

??????執行過程如下圖:

2、優點

???????這使得每次都是只對整個半區進行內存回收;

???????內存分配時也不用考慮內存碎片等問題(可使用"指針碰撞"的方式分配內存);

??????實現簡單,運行高效;

???????(關于"指針碰撞"請參考《Java對象在HotSpot虛擬機中的創建過程》)

3、缺點

(A)、空間浪費

??????可用內存縮減為原來的一半,太過浪費(解決:可以改良,不按1:1比例劃分);

(B)、效率隨對象存活率升高而變低

??????當對象存活率較高時,需要進行較多復制操作,效率將會變低(解決:后面的標記-整理算法);

4、應用場景

??????現在商業JVM都采用這種算法(通過改良缺點1)來回收新生代;

新生代:新建的對象都放到新生代

老年代:多次回收沒有被回收的對象或者大對象

??????如Serial收集器、ParNew收集器、Parallel Scavenge收集器、、G1(從局部看);

5、HotSpot虛擬機的改良算法

(A)、弱代理論

???????分代垃圾收集基于弱代理論(weak generational hypothesis),具體描述如下:

???????(1)、大多數分配了內存的對象并不會存活太長時間,在處于年輕代時就會死掉;

???????(2)、很少有對象會從老年代變成年輕代;

???????其中IBM研究表明:新生代中98%的對象都是"朝生夕死";

????????所以并不需要按1:1比例來劃分內存(解決了缺點1);

(B)、HotSpot虛擬機新生代內存布局及算法

??????????????????????(1)、將新生代內存分為一塊較大的Eden空間和兩塊較小的Survivor空間;

??????????????????????(2)、每次使用Eden和其中一塊Survivor;

??????????????????????(3)、當回收時,將Eden和使用中的Survivor中還存活的對象一次性復制到另外一塊Survivor;

??????????????????????(4)、而后清理掉Eden和使用過的Survivor空間;

??????????????????????(5)、后面就使用Eden和復制到的那一塊Survivor空間,重復步驟3;

?????????默認Eden:Survivor=8:1,即每次可以使用90%的空間,只有一塊Survivor的空間被浪費;

(C)、分配擔保

???????如果另一塊Survivor空間沒有足夠空間存放上一次新生代收集下來的存活對象時,這些對象將直接通過分配擔保機制(Handle Promotion)進入老年代;

???????分配擔保在以后講解垃圾收集器執行規則時再詳解;

???????更多請參考:http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/generations.html#sthref16

3、標記-整理算法

???????"標記-整理"(Mark-Compact)算法是根據老年代的特點提出的。

1、算法思路

(1)、標記

??????標記過程與"標記-清除"算法一樣;

(2)、整理

???????但后續不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動;

???????然后直接清理掉端邊界以外的內存;

執行過程如下圖:

2、優點

(A)、不會像復制算法,效率隨對象存活率升高而變低

???????老年代特點:

???????對象存活率高,沒有額外的空間可以分配擔保;

???????所以老年代一般不能直接選用復制算法算法;

???????而選用標記-整理算法;

(B)、不會像標記-清除算法,產生內存碎片

???????因為清除前,進行了整理,存活對象都集中到空間一側;

3、缺點

???????主要是效率問題:除像標記-清除算法的標記過程外,還多了需要整理的過程,效率更低;

4、應用場景

???????很多垃圾收集器采用這種算法來回收老年代;

??????如Serial Old收集器、G1(從整體看);

4、分代收集算法

???????"分代收集"(Generational Collection)算法結合不同的收集算法處理不同區域。

1、算法思路

???????基于前面說的弱代理論,其實并沒有什么新的思想;

???????只是根據對象存活周期的不同將內存劃分為幾塊;

???????這樣就可以根據各個年代的特點采用最適當的收集算法;

???????一般把Java堆分為新生代和老年代;

(A)、新生代

???????每次垃圾收集都有大批對象死去,只有少量存活;

???????所以可采用復制算法;

(B)、老年代

???????對象存活率高,沒有額外的空間可以分配擔保;

??????使用"標記-清理"或"標記-整理"算法;

??????結合上面對新生代的內存劃分介紹和上篇文章對Java堆的介紹,可以得出HotSpot虛擬機一般的年代內存劃分,如下圖:

2、優點??????

???????可以根據各個年代的特點采用最適當的收集算法;

?

3、缺點??????

???????仍然不能控制每次垃圾收集的時間;

4、應用場景

??????目前幾乎所有商業虛擬機的垃圾收集器都采用分代收集算法;

??????如HotSpot虛擬機中全部垃圾收集器:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1(也保留);

轉載于:https://www.cnblogs.com/xiaolovewei/p/8027245.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370260.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370260.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370260.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python常用函數中文_【python】python常用函數

urlencode與urldecode當url中包含中文或者參數包含中文,需要對中文或者特殊字符(/、&)做編碼轉換。urlencode的本質:把字符串轉為gbk編碼,再把\x替換成%。如果終端是utf8編碼的,需要把結果再轉成utf8輸出,否則會亂…

帶有批注的Spring硒測試

這篇文章描述了如何在Java中實現Selenium測試。 它的靈感來自Alex Collins的帖子,并帶有注釋。 該代碼可在GitHub的Spring-Selenium-Test目錄中找到。 一些替代方法和更輕巧的技術可用于對Spring MVC應用程序進行單元測試。 要進行單元測試服務,請參見此…

sizeof運算符

sizeof是一個單目運算符&#xff0c;它的運算對象是變量或數據類型&#xff0c;運算結果為一個整數。運算的一般形式如下: sizeof(<類型或變量名>) 它只針對數據類型&#xff0c;而不針對變量&#xff01; 若運算對象為變量&#xff0c;則所求的結果是這個變量占用的內存…

oracle 日志切換太頻繁,診斷一次Oracle日志切換頻繁的問題

日志切換&#xff0c;就是生成的日志太大&#xff0c;數據塊的變化太頻繁。Snap IdSnap TimeSessionsCursors/SessionBegin Snap:1456009-Dec-15 04:00:48594.5End Snap:1456109-Dec-15 05:00:59544.6Elapsed:60.19 (mins)DB Time:82.47 (mins)1s產生2M的日志。Per SecondPer T…

Flex布局(一)flex-direction

采用Flex布局的元素&#xff0c;被稱為Flex容器(flex container)&#xff0c;簡稱"容器"。其所有子元素自動成為容器成員&#xff0c;成為Flex項目(Flex item)&#xff0c;簡稱"項目" Flex-direction調整主軸方向&#xff08;默認為水平方向&#xff09;包…

【升級版】如何使用阿里云云解析API實現動態域名解析,搭建私有服務器【含可執行文件和源碼】...

原文地址&#xff1a;http://www.yxxrui.cn/article/179.shtml 未經許可請勿轉載&#xff0c;如有疑問&#xff0c;請聯系作者&#xff1a;yxxrui163.com 我遇到的問題&#xff1a;公司的網絡沒有固定的公網IP地址&#xff0c;但是需要能夠保證的是&#xff0c;每次動態分配的I…

Java管理擴展

什么是JMX&#xff1f; Java管理擴展&#xff08;JMX&#xff09;是一種API&#xff0c;用于管理或監視各種資源&#xff0c;例如應用程序&#xff0c;設備&#xff0c;服務&#xff0c;當然還有JVM。 通過Java社區流程&#xff08;JCP&#xff09;開發&#xff0c;JMX技術被構…

登錄網頁后要彈出一個新標簽_連永久鏈接都不會,還做什么新媒體?

上次給主編大大發的預覽鏈接失效了&#xff0c;被罵得狗血淋頭。大部分運營人可能都遇到過這種情況&#xff0c;忽視了預覽生成的鏈接只是臨時的&#xff0c;在12小時后或超過500閱讀量后就會失效。一個疏忽&#xff0c;給自己帶來了不必要的麻煩&#xff0c;耽誤工作&#xff…

混頻通信的matlab仿真,基于MATLAB的擴頻通信系統仿真研究—上海交通大學

基于MATLAB 的擴頻通信系統仿真研究范偉 翟傳潤 戰興群(上海交通大學電子信息與電氣工程學院&#xff0c;200030&#xff0c;上海)摘要 本文闡述了擴展頻譜通信技術的理論基礎和實現方法&#xff0c;利用MATLAB 提供的可視化工具Simulink 建立了擴頻通信系統仿真模型&#xff0…

static_cast與dynamic_cast轉換

static_cast與dynamic_cast轉換   一 C語言中存在著兩種類型轉換&#xff1a; 隱式轉換和顯式轉換 隱式轉換&#xff1a;不同數據類型之間賦值和運算&#xff0c;函數調用傳遞參數……編譯器完成 char ch;int i ch; 顯示轉換&#xff1a;在類型前增加 &#xff1a;&#xff…

vue使用iview Timeline 時間軸不顯示問題

vue Timeline 時間軸不顯示渲染的效果 官網代碼 <Timeline pending><TimelineItem>發布1.0版本</TimelineItem><TimelineItem>發布2.0版本</TimelineItem><TimelineItem>發布3.0版本</TimelineItem><TimelineItem><a href…

python 重置索引_python pandas 對series和dataframe的重置索引reindex方法

reindex更多的不是修改pandas對象的索引&#xff0c;而只是修改索引的順序&#xff0c;如果修改的索引不存在就會使用默認的None代替此行。且不會修改原數組&#xff0c;要修改需要使用賦值語句。series.reindex()import pandas as pdimport numpy as npobj pd.Series(range(4…

Java EE 6 Web配置文件。 在云上。 簡單。

Java SE還可以。 Java EE是邪惡的。 這就是我一直想的。 好吧&#xff0c;現在不再了。 讓我分享我的經驗。 幾周前&#xff0c;我開始考慮將舊版spring hibernate tomcat應用程序移植到新平臺上&#xff1a; SAP NetWeaver云 。 我知道您在極客那里的想法&#xff1a;…

Kubernetes核心概念總結

1、基礎架構 1.1 Master Master節點上面主要由四個模塊組成&#xff1a;APIServer、scheduler、controller manager、etcd。 APIServer。APIServer負責對外提供RESTful的Kubernetes API服務&#xff0c;它是系統管理指令的統一入口&#xff0c;任何對資源進行增刪改查的操作都要…

七、spring boot 1.5.4 集成shiro+cas,實現單點登錄和權限控制

1.安裝cas-server-3.5.2 官網&#xff1a;https://github.com/apereo/cas/releases/tag/v3.5.2 下載地址&#xff1a;cas-server-3.5.2-release.zip 安裝參考文章&#xff1a;http://blog.csdn.net/xuxuchuan/article/details/54924933 注意&#xff1a; 輸入 <tomcat_key&g…

php連接mysql數據,php連接mysql數據庫

$sql_link mysql_connect("主機名","登入用戶名","登入用戶名密碼");如果連接成功&#xff0c;就會返回一個mysql句柄,可以簡單的理解成這個$sql_link 是php跟mysql的一個橋梁&#xff0c;通過該橋梁我們可以進入到mysql。進入到mysql之后&…

CSS-自定義變量

使用背景&#xff1a; 一些常見的例子&#xff1a;為風格統一而使用顏色變量一致的組件屬性&#xff08;布局&#xff0c;定位等&#xff09;避免代碼冗余*更方便的從CSS向JS傳遞數據&#xff08;例如媒體斷點&#xff09; 為什么使用&#xff1a; 以下幾點是未來CSS屬性的簡短…

url存在寬字節跨站漏洞_利用WebSocket跨站劫持(CSWH)漏洞接管帳戶

在一次漏洞懸賞活動中&#xff0c;我發現了一個使用WebSocket連接的應用&#xff0c;所以我檢查了WebSocket URL&#xff0c;發現它很容易受到CSWH的攻擊(WebSocket跨站劫持)有關CSWH的更多詳細信息&#xff0c;可以訪問以下鏈接了解https://www.christian-schneider.net/Cross…

php 數組對比 unset,如何區分PHP中unset,array_splice的區別

1.使用的函數a.函數unset()unset ( mixed $var , mixed $... ? ) : voidunset()銷毀指定的變量。b.函數array_slice()array_splice(array,start,length,array)array表示數組。start表示刪除元素的開始位置。length表示被移除的元素個數&#xff0c;也是被返回數組的長度。(可…

MapReduce算法–二級排序

我們將繼續進行有關實現MapReduce算法的系列文章&#xff0c;該系列可在使用MapReduce進行數據密集型文本處理中找到。 本系列的其他文章&#xff1a; 使用MapReduce進行數據密集型文本處理 使用MapReduce進行數據密集型文本處理-本地聚合第二部分 使用Hadoop計算共現矩陣 …