久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 淺談Java垃圾回收機制

淺談Java垃(la)圾(ji)回收(shou)機制 時間:2019-03-05      來源:華清遠見

一(yi)、淺(qian)談(tan)java中的垃(la)圾回收機制

根據很多同(tong)(tong)學與朋友,日常工作與面(mian)試時經(jing)常會被問到JVM垃圾回收(shou)機(ji)制,接下(xia)來博主就給你捋一捋,疏(shu)理知識(shi)點,如(ru)有不同(tong)(tong)意見(jian)或建議(yi),歡迎聯系(xi)博主以(yi)便交流。

1.GC技術背景

淺談JVM垃(la)圾(ji)回(hui)收的(de)前(qian)世今。說起垃(la)圾(ji)回(hui)收機(ji)制(zhi)(GC),大部分(fen)人都把(ba)這項技術當(dang)做Java語言(yan)的(de)伴生產(chan)物(wu)。事(shi)實上(shang),GC的(de)歷史比(bi)Java久(jiu)遠,早(zao)在1960年Lisp這門語言(yan)中就使用了內存動態分(fen)配和垃(la)圾(ji)回(hui)收技術。

2.JVM內存回收

程(cheng)序(xu)(xu)員(yuan)們知道,jvm內(nei)(nei)存結構分為(wei)五(wu)大區域(yu):程(cheng)序(xu)(xu)計(ji)數器、虛(xu)擬機(ji)棧(zhan)、本地方法(fa)(fa)棧(zhan)、堆區、方法(fa)(fa)區。其中虛(xu)擬機(ji)棧(zhan)、本地方法(fa)(fa)棧(zhan)與(yu)程(cheng)序(xu)(xu)計(ji)數器這3個區域(yu)隨線(xian)(xian)程(cheng)而(er)生(sheng)、隨線(xian)(xian)程(cheng)而(er)滅,因此(ci)就不需(xu)要考慮過多(duo)內(nei)(nei)存垃圾回收(shou)問(wen)題,因為(wei)一個方法(fa)(fa)調用結束或者(zhe)線(xian)(xian)程(cheng)結束時,內(nei)(nei)存自(zi)然就跟隨著回收(shou)了(le)。

我們(men)就把重點放在(zai)方法區與(yu)堆區,這部(bu)分(fen)內存的分(fen)配和(he)回收(shou)是動態(tai)的,正是垃圾收(shou)集器所需(xu)關注(zhu)的部(bu)分(fen)。

二、GC中的算法

1.直面問題(ti),哪些可(ke)以回收,哪些暫時(shi)還(huan)不能回收?

垃圾收(shou)(shou)集器(qi)在對堆(dui)區(qu)和(he)方(fang)法(fa)區(qu)進行回(hui)收(shou)(shou)工作前,首(shou)先肯定確定這些區(qu)域內對象哪些可(ke)以被回(hui)收(shou)(shou),哪些暫時(shi)還不能回(hui)收(shou)(shou),這時(shi)就(jiu)要用到判斷對象是否存(cun)活的算法(fa)!如(ru)何失去任(ren)何引用,垃圾收(shou)(shou)集器(qi)就(jiu)把它收(shou)(shou)走。

(1)引用計數(shu)算(suan)法

早期(qi)策略(lve)。在這(zhe)種算法中(zhong),堆中(zhong)每個(ge)對(dui)(dui)象實(shi)例(li)都(dou)有一(yi)個(ge)引(yin)(yin)(yin)用(yong)(yong)計數。當(dang)(dang)(dang)一(yi)個(ge)對(dui)(dui)象被(bei)創建時(shi),就將(jiang)該對(dui)(dui)象實(shi)例(li)分配給一(yi)個(ge)變量,該變量計數設置(zhi)為(wei)(wei)(wei)1。當(dang)(dang)(dang)任(ren)何(he)(he)其它變量被(bei)賦(fu)值為(wei)(wei)(wei)這(zhe)個(ge)對(dui)(dui)象的(de)(de)引(yin)(yin)(yin)用(yong)(yong)時(shi),計數加1(但(dan)當(dang)(dang)(dang)一(yi)個(ge)對(dui)(dui)象實(shi)例(li)的(de)(de)某個(ge)引(yin)(yin)(yin)用(yong)(yong)超(chao)過了(le)生命周期(qi)或者被(bei)設置(zhi)為(wei)(wei)(wei)一(yi)個(ge)新值時(shi),對(dui)(dui)象實(shi)例(li)的(de)(de)引(yin)(yin)(yin)用(yong)(yong)計數器(qi)減(jian)1。任(ren)何(he)(he)引(yin)(yin)(yin)用(yong)(yong)計數器(qi)為(wei)(wei)(wei)0的(de)(de)對(dui)(dui)象實(shi)例(li)可以被(bei)當(dang)(dang)(dang)作垃(la)圾收(shou)集(ji)(ji)。當(dang)(dang)(dang)一(yi)個(ge)對(dui)(dui)象實(shi)例(li)被(bei)垃(la)圾收(shou)集(ji)(ji)時(shi),它引(yin)(yin)(yin)用(yong)(yong)的(de)(de)任(ren)何(he)(he)對(dui)(dui)象實(shi)例(li)的(de)(de)引(yin)(yin)(yin)用(yong)(yong)計數器(qi)減(jian)1。

缺點:循環引(yin)用時無效

如(ru):如(ru)父(fu)對(dui)象(xiang)(xiang)有一個對(dui)子對(dui)象(xiang)(xiang)的引用,子對(dui)象(xiang)(xiang)反(fan)過(guo)來引用父(fu)對(dui)象(xiang)(xiang)。

(2)可達性(xing)分析算法

可達性分析算法是(shi)從離散數學(xue)中引(yin)入的(de)(de)(de)(de),也是(shi)如今正在使用(yong)(yong)(yong)(yong)的(de)(de)(de)(de)策略,程序把所(suo)有的(de)(de)(de)(de)引(yin)用(yong)(yong)(yong)(yong)關系(xi)看作一(yi)張圖(DOM圖類似),從一(yi)個(ge)節點(dian)(dian)(dian)GC ROOT開始,尋找對應的(de)(de)(de)(de)引(yin)用(yong)(yong)(yong)(yong)節點(dian)(dian)(dian),找到這個(ge)節點(dian)(dian)(dian)以后(hou),繼(ji)續尋找這個(ge)節點(dian)(dian)(dian)的(de)(de)(de)(de)引(yin)用(yong)(yong)(yong)(yong)節點(dian)(dian)(dian),就如遞(di)歸思想一(yi)般,遍歷(li)所(suo)有,當所(suo)有的(de)(de)(de)(de)引(yin)用(yong)(yong)(yong)(yong)節點(dian)(dian)(dian)尋找完畢(bi)之后(hou),剩余的(de)(de)(de)(de)節點(dian)(dian)(dian)則被認為是(shi)沒有被引(yin)用(yong)(yong)(yong)(yong)到的(de)(de)(de)(de)節點(dian)(dian)(dian),即無用(yong)(yong)(yong)(yong)的(de)(de)(de)(de)節點(dian)(dian)(dian),無用(yong)(yong)(yong)(yong)的(de)(de)(de)(de)節點(dian)(dian)(dian)將會被判定為是(shi)可回收的(de)(de)(de)(de)對象。

三、引用與回收問題

無論是(shi)通過(guo)引用(yong)計數(shu)算(suan)法判(pan)斷對象的引用(yong)數(shu)量,還是(shi)通過(guo)可(ke)達(da)性分析算(suan)法判(pan)斷對象的引用(yong)鏈是(shi)否可(ke)達(da),判(pan)定對象是(shi)否存(cun)活都與(yu)“引用(yong)”有關。

當對象失去所有(you)引用時,我(wo)們就(jiu)(jiu)可以說對象生命周期結束了(le),即為死亡,就(jiu)(jiu)該回收(shou)它啦。

四、常見的垃圾回收器(qi)

1.Serial收集器

新生代單線(xian)程收集器,標(biao)記和清理都(dou)是(shi)單線(xian)程,優點是(shi)簡(jian)單高效。是(shi)client級別默認(ren)的(de)GC方(fang)式。

2.Serial Old收集器(qi)

老(lao)年代(dai)單線程收集器(qi),Serial收集器(qi)的老(lao)年代(dai)版本。

3.ParNew收(shou)集(ji)器

新(xin)生代(dai)收(shou)集器(qi),可以(yi)認(ren)為(wei)是Serial收(shou)集器(qi)的多線程版本(ben),在多核CPU環境下有(you)著比Serial更(geng)好的表現。

4.Parallel Scavenge收(shou)集(ji)器(qi)

并行收集(ji)器(qi),追求(qiu)高吞吐量(liang),高效利用(yong)CPU。吞吐量(liang)一般(ban)為(wei)99%, 吞吐量(liang)= 用(yong)戶線(xian)程時間/(用(yong)戶線(xian)程時間+GC線(xian)程時間)。適合后(hou)臺應(ying)用(yong)等對(dui)交互相應(ying)要求(qiu)不高的(de)場景。是server級別默認采用(yong)的(de)GC方式。

5.Parallel Old收集(ji)器(qi)

Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量優先。

6.CMS(Concurrent Mark Sweep)收集(ji)器

高并發、低停頓(dun),追(zhui)求最短GC回收停頓(dun)時(shi)間,cpu占用比較高,響應時(shi)間快(kuai),停頓(dun)時(shi)間短,多核cpu 追(zhui)求高響應時(shi)間的選(xuan)擇。

五(wu)、垃圾回(hui)收機制什么時候(hou)觸發?

由于會遇到的問題不(bu)一樣,因此垃圾(ji)回(hui)收區域、時間、方(fang)法也(ye)不(bu)一樣。GC有兩(liang)種類(lei)型:Full GC  &  Scavenge GC 。

1.FULL GC  

GC在優先級(ji)最低的線程中運行(xing),一般在應用(yong)程序空閑即沒有(you)應用(yong)線程在運行(xing)時被調用(yong)。

對(dui)整(zheng)個(ge)堆(dui)進行(xing)整(zheng)理,包(bao)括Young(新生區)、Tenured(老年區)和(he)Perm(靜態區)。Full GC因為(wei)需要(yao)對(dui)整(zheng)個(ge)堆(dui)進行(xing)回收,所以比Scavenge GC要(yao)慢,因此(ci)應該盡可能(neng)減少(shao)Full GC的(de)次數(shu)。在對(dui)JVM調優的(de)過程中,很(hen)大一部(bu)分工(gong)作就(jiu)是(shi)對(dui)于Full GC的(de)調節。

但下(xia)面的條(tiao)件(jian)例外(wai)。

2.Scavenge GC

(1)Java堆(dui)內存不足(zu)時,Scavenge GC會被調用。

(2)當(dang)應用線(xian)程在運行(xing),并(bing)在運行(xing)過程中創(chuang)建新對象,若(ruo)這時(shi)內存空間(jian)不(bu)足(zu),JVM就會(hui)(hui)強制調用Scavenge GC線(xian)程。若(ruo)GC一次(ci)之后仍(reng)不(bu)能滿足(zu)內存分配,JVM會(hui)(hui)再進行(xing)兩(liang)次(ci)GC,若(ruo)仍(reng)無(wu)法滿足(zu)要(yao)求,則JVM將報“out of memory”的錯誤(wu),java虛擬機將停止運行(xing)。

六、GC的兩個重(zhong)要(yao)方法

(1)System.gc()方法

  使用System.gc()可以(yi)不管JVM使用的是哪(na)一種垃圾回收的算法,都可以(yi)請求Java的垃圾回收。

在命令行中(zhong)有一個參數-verbosegc可(ke)以(yi)查看Java使(shi)用的(de)堆內存的(de)情況,由于這種(zhong)方法(fa)會影響系統性(xing)能,不推薦使(shi)用。

(2)finalize()方法

  在JVM垃(la)圾(ji)回收(shou)器收(shou)集一(yi)個對象之前(qian),一(yi)般要(yao)求程(cheng)序(xu)調(diao)用適當的方法釋(shi)放資(zi)源,但在沒(mei)有明(ming)確釋(shi)放資(zi)源的情況下,Java提供(gong)了缺省機制(zhi)來(lai)終止該(gai)對象心釋(shi)放資(zi)源,這個方法就是finalize()。

它的(de)原(yuan)型為(wei):protected void finalize() throws Throwable   

在(zai)finalize()方法返回之后,對象消失(shi),垃圾收(shou)集開始執行。之所(suo)以(yi)要使(shi)用finalize(),是存在(zai)著垃圾回收(shou)器不能(neng)處理(li)的特殊情況。

七、GC使用與性能優化管理(li)

(1)不要顯(xian)式(shi)調(diao)用System.gc()。此函數建(jian)議(yi)JVM進行主(zhu)GC,雖(sui)然只(zhi)是建(jian)議(yi)而非一(yi)定,但很多(duo)情況下(xia)它會觸發主(zhu)GC,從而增加主(zhu)GC的頻率,也即增加了間歇性停頓(dun)的次(ci)數。大(da)大(da)的影響系(xi)統性能。

 (2)盡量(liang)減(jian)少臨時對(dui)象的(de)(de)使用(yong)(yong)。臨時對(dui)象在跳出函數調用(yong)(yong)后,會成為垃圾(ji)(ji),少用(yong)(yong)臨時變量(liang)就相當于減(jian)少了垃圾(ji)(ji)的(de)(de)產(chan)生(sheng),從而延長了出現上述第(di)二個觸發條件出現的(de)(de)時間,減(jian)少了主GC的(de)(de)機會。

(3)對象(xiang)不用(yong)時最(zui)好顯式置為Null。一般(ban)而(er)言,為Null的(de)對象(xiang)都會被作為垃圾(ji)處理,所以將不用(yong)的(de)對象(xiang)顯式地設為Null,有利(li)于GC收集器(qi)判定垃圾(ji),從而(er)提(ti)高了(le)GC的(de)效率。

(4)盡量使(shi)用(yong)StringBuffer,而(er)不用(yong)String來累加字(zi)(zi)(zi)符串。由于String是(shi)固定長(chang)的(de)字(zi)(zi)(zi)符串對(dui)(dui)象(xiang)(xiang)(xiang),累加String對(dui)(dui)象(xiang)(xiang)(xiang)時(shi),并非在一個String對(dui)(dui)象(xiang)(xiang)(xiang)中擴(kuo)(kuo)增,而(er)是(shi)重新創建新的(de)String對(dui)(dui)象(xiang)(xiang)(xiang),如Str5=Str1+Str2+Str3+Str4,這(zhe)條(tiao)語句執行(xing)過(guo)程(cheng)中會產生多個垃(la)圾(ji)對(dui)(dui)象(xiang)(xiang)(xiang),因為對(dui)(dui)次作“+”操作時(shi)都必須創建新的(de)String對(dui)(dui)象(xiang)(xiang)(xiang),但這(zhe)些(xie)過(guo)渡對(dui)(dui)象(xiang)(xiang)(xiang)對(dui)(dui)系統來說(shuo)是(shi)沒(mei)有實際(ji)意義的(de),只會增加更(geng)多的(de)垃(la)圾(ji)。避免這(zhe)種情況可以改用(yong)StringBuffer來累加字(zi)(zi)(zi)符串,因StringBuffer是(shi)可變(bian)長(chang)的(de),它在原有基礎上進行(xing)擴(kuo)(kuo)增,不會產生中間對(dui)(dui)象(xiang)(xiang)(xiang)。

(5)能用基(ji)本(ben)(ben)類型如Int,Long,就不用Integer,Long對象(xiang)。基(ji)本(ben)(ben)類型變(bian)量占用的內存資(zi)源(yuan)比相應(ying)對象(xiang)占用的少得多,如果(guo)沒有必要,最好(hao)使用基(ji)本(ben)(ben)變(bian)量。

(6)盡量(liang)(liang)(liang)少用(yong)靜(jing)態對象變(bian)量(liang)(liang)(liang)。靜(jing)態變(bian)量(liang)(liang)(liang)屬于(yu)全局變(bian)量(liang)(liang)(liang),不會被GC回(hui)收,它們會一直占(zhan)用(yong)內(nei)存。

(7)注意(yi)分散對(dui)象(xiang)(xiang)創建(jian)或刪除(chu)(chu)的時間(jian)。集中在短(duan)時間(jian)內(nei)大(da)量創建(jian)新對(dui)象(xiang)(xiang),特別(bie)是大(da)對(dui)象(xiang)(xiang),會導(dao)致突然需要大(da)量內(nei)存(cun),JVM在面臨這(zhe)種(zhong)情況時,只能進行主GC,以回(hui)收內(nei)存(cun)或整(zheng)合內(nei)存(cun)碎片,從而(er)增(zeng)加主GC的頻率。集中刪除(chu)(chu)對(dui)象(xiang)(xiang),道理也(ye)是一(yi)樣的。

八、結束語

Java垃(la)圾(ji)回(hui)收(shou)機(ji)制靠一(yi)篇(pian)博(bo)文很(hen)難講解完(wan),雖然(ran)本人做了很(hen)大努力,但是還得投降(jiang),對于各個垃(la)圾(ji)收(shou)集器(qi)的區別、運行過程中各內存區域參(can)數的設置、GC日志的查看(kan)等內容,希望繼續關注博(bo)客,聯系博(bo)主,我會不斷的更新的!!

上一篇:C語言中的邏輯值

下一篇:C語言:chmod命令

熱(re)點(dian)文章推薦
華(hua)清(qing)學員就業榜單
高(gao)薪學員經驗分享
熱點新聞推薦
前臺專(zhuan)線:010-82525158 企(qi)業培訓洽(qia)談專線:010-82525379 院校合(he)作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部