国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Java垃圾回收機(jī)制小結(jié)

一.誰在做Garbage Collection?

  一種流行的說法:在C++里,是系統(tǒng)在做垃圾回收;而在Java里,是Java自身在做。

  在C++里,釋放內(nèi)存是手動(dòng)處理的,要用delete運(yùn)算符來釋放分配的內(nèi)存。這是流行的說法。確切地說,是應(yīng)用認(rèn)為不需要某實(shí)體時(shí),就需用delete 告訴系統(tǒng),可以回收這塊空間了。這個(gè)要求,對(duì)編碼者來說,是件很麻煩、很難做到的事。隨便上哪個(gè)BBS,在C/C++版塊里總是有一大堆關(guān)于內(nèi)存泄漏的話題。

  Java采用一種不同的,很方便的方法:Garbage Collection。垃圾回收機(jī)制放在JVM里。JVM完全負(fù)責(zé)垃圾回收事宜,應(yīng)用只在需要時(shí)申請(qǐng)空間,而在拋棄對(duì)象時(shí)不必關(guān)心空間回收問題。

  二.對(duì)象在啥時(shí)被丟棄?

  在C++里,當(dāng)對(duì)象離開其作用域時(shí),該對(duì)象即被應(yīng)用拋棄。

  在Java里,對(duì)象的生命期不再與其作用域有關(guān),而僅僅與引用有關(guān)。

  Java的垃圾回收機(jī)制一般包含近十種算法。對(duì)這些算法中的多數(shù),我們不必予以關(guān)心。只有其中最簡單的一個(gè):引用計(jì)數(shù)法,與編碼有關(guān)。

  一個(gè)對(duì)象,可以有一個(gè)或多個(gè)引用變量指向它。當(dāng)一個(gè)對(duì)象不再有任何一個(gè)引用變量指向它時(shí),這個(gè)對(duì)象就被應(yīng)用拋棄了。或者說,這個(gè)對(duì)象可以被垃圾回收機(jī)制回收了。這就是說,當(dāng)不存在對(duì)某對(duì)象的任何引用時(shí),就意味著,應(yīng)用告訴JVM:我不要這個(gè)對(duì)象,你可以回收了。

  JVM的垃圾回收機(jī)制對(duì)堆空間做實(shí)時(shí)檢測(cè)。當(dāng)發(fā)現(xiàn)某對(duì)象的引用計(jì)數(shù)為0時(shí),就將該對(duì)象列入待回收列表中。但是,并不是馬上予以銷毀。

  三.丟棄就被回收?

  該對(duì)象被認(rèn)定為沒有存在的必要了,那么它所占用的內(nèi)存就可以被釋放。被回收的內(nèi)存可以用于后續(xù)的再分配。

  但是,并不是對(duì)象被拋棄后當(dāng)即被回收的。JVM進(jìn)程做空間回收有較大的系統(tǒng)開銷。如果每當(dāng)某應(yīng)用進(jìn)程丟棄一個(gè)對(duì)象,就立即回收它的空間,勢(shì)必會(huì)使整個(gè)系統(tǒng)的運(yùn)轉(zhuǎn)效率非常低下。前面說過,JVM的垃圾回收機(jī)制有多個(gè)算法。除了引用計(jì)數(shù)法是用來判斷對(duì)象是否已被拋棄外,其它算法是用來確定何時(shí)及如何做回收。 JVM的垃圾回收機(jī)制要在時(shí)間和空間之間做個(gè)平衡。

  因此,為了提高系統(tǒng)效率,垃圾回收器通常只在滿足兩個(gè)條件時(shí)才運(yùn)行:即有對(duì)象要回收且系統(tǒng)需要回收。切記垃圾回收要占用時(shí)間,因此,Java運(yùn)行時(shí)系統(tǒng)只在需要的時(shí)候才使用它。因此你無法知道垃圾回收發(fā)生的精確時(shí)間。

  四.沒有引用變量指向的對(duì)象有用嗎?

  前面說了,沒掛上引用變量的對(duì)象是被應(yīng)用丟棄的,這意味著,它在堆空間里是個(gè)垃圾,隨時(shí)可能被JVM回收。不過,這里有個(gè)不是例外的例外。對(duì)于一次性使用的對(duì)象(有些書稱之為臨時(shí)對(duì)象),可以不用引用變量指向它。舉個(gè)最簡單也最常見的例子:System.out.println(“I am Java!”);就是創(chuàng)建了一個(gè)字符串對(duì)象后,直接傳遞給println()方法。

  五.應(yīng)用能干預(yù)垃圾回收嗎?

  許多人對(duì)Java的垃圾回收不放心,希望在應(yīng)用代碼里控制JVM的垃圾回收運(yùn)作。這是不可能的事。對(duì)垃圾回收機(jī)制來說,應(yīng)用只有兩個(gè)途徑發(fā)消息給JVM。第一個(gè)前面已經(jīng)說了,就是將指向某對(duì)象的所有引用變量全部移走。這就相當(dāng)于向JVM發(fā)了一個(gè)消息:這個(gè)對(duì)象不要了。第二個(gè)是調(diào)用庫方法 System.gc(),多數(shù)書里說調(diào)用它讓Java做垃圾回收。

  第一個(gè)是一個(gè)告知,而調(diào)用System.gc()也僅僅是一個(gè)請(qǐng)求。JVM接受這個(gè)消息后,并不是立即做垃圾回收,而只是對(duì)幾個(gè)垃圾回收算法做了加權(quán),使垃圾回收操作容易發(fā)生,或提早發(fā)生,或回收較多而已。

  希望JVM及時(shí)回收垃圾,是一種需求。其實(shí),還有相反的一種需要:在某段時(shí)間內(nèi)最好不要回收垃圾。要求運(yùn)行速度最快的實(shí)時(shí)系統(tǒng),特別是嵌入式系統(tǒng),往往希望如此。

  Java的垃圾回收機(jī)制是為所有Java應(yīng)用進(jìn)程服務(wù)的,而不是為某個(gè)特定的進(jìn)程服務(wù)的。因此,任何一個(gè)進(jìn)程都不能命令垃圾回收機(jī)制做什么、怎么做或做多少。

  六.對(duì)象被回收時(shí)要做的事

  一個(gè)對(duì)象在運(yùn)行時(shí),可能會(huì)有一些東西與其關(guān)連。因此,當(dāng)對(duì)象即將被銷毀時(shí),有時(shí)需要做一些善后工作??梢园堰@些操作寫在finalize()方法(常稱之為終止器)里。

  protected void finalize()

  {

  // finalization code here

  }

  這個(gè)終止器的用途類似于C++里的析構(gòu)函數(shù),而且都是自動(dòng)調(diào)用的。但是,兩者的調(diào)用時(shí)機(jī)不一樣,使兩者的表現(xiàn)行為有重大區(qū)別。C++的析構(gòu)函數(shù)總是當(dāng)對(duì)象離開作用域時(shí)被調(diào)用。這就是說,C++析構(gòu)函數(shù)的調(diào)用時(shí)機(jī)是確定的,且是可被應(yīng)用判知的。但是,Java終止器卻是在對(duì)象被銷毀時(shí)調(diào)用。一旦垃圾收集器準(zhǔn)備好釋放無用對(duì)象占用的存儲(chǔ)空間,它首先調(diào)用那些對(duì)象的finalize()方法,然后才真正回收對(duì)象的內(nèi)存。由上所知,被丟棄的對(duì)象何時(shí)被銷毀,應(yīng)用是無法獲知的。而且,對(duì)于大多數(shù)場(chǎng)合,被丟棄對(duì)象在應(yīng)用終止后仍未銷毀。

  在編碼時(shí),考慮到這一點(diǎn)。譬如,某對(duì)象在運(yùn)作時(shí)打開了某個(gè)文件,在對(duì)象被丟棄時(shí)不關(guān)閉它,而是把文件關(guān)閉語句寫在終止器里。這樣做對(duì)文件操作會(huì)造成問題。如果文件是獨(dú)占打開的,則其它對(duì)象將無法訪問這個(gè)文件。如果文件是共享打開的,則另一訪問該文件的對(duì)象直至應(yīng)用終結(jié)仍不能讀到被丟棄對(duì)象寫入該文件的新內(nèi)容。

  至少對(duì)于文件操作,編碼者應(yīng)認(rèn)清Java終止器與C++析構(gòu)函數(shù)之間的差異。

  那么,當(dāng)應(yīng)用終止,會(huì)不會(huì)執(zhí)行應(yīng)用中的所有finalize()呢?據(jù)Bruce Eckel在Thinking in Java里的觀點(diǎn):“到程序結(jié)束的時(shí)候,并非所有收尾模塊都會(huì)得到調(diào)用”。這還僅僅是指應(yīng)用正常終止的場(chǎng)合,非正常終止呢?因此,哪些收尾操作可以放在 finalize()里,是需要酌酎的。

  七.Thinking ing java 一書中也對(duì)垃圾回收做了一些小結(jié)

  java垃圾回收,主要是靠一個(gè)低優(yōu)先級(jí)的進(jìn)程負(fù)責(zé)回收,注意,不是后臺(tái)的進(jìn)程

  他的優(yōu)點(diǎn)是邊回收,邊調(diào)整堆使其緊湊

  主要有以下幾種算法:

  1.引用計(jì)數(shù)

  該算法在java虛擬機(jī)沒被使用過,主要是循環(huán)引用問題,因?yàn)橛?jì)數(shù)并不記錄誰指向他,無法發(fā)現(xiàn)這些交互自引用對(duì)象。

  怎么計(jì)數(shù)?

  當(dāng)引用連接到對(duì)象時(shí),對(duì)象計(jì)數(shù)加1

  當(dāng)引用離開作用域或被置為null時(shí)減1

  怎么回收?

  遍歷對(duì)象列表,計(jì)數(shù)為0就釋放

  有什么問題?

  循環(huán)引用問題。

  2.標(biāo)記算法

  標(biāo)記算法的思想是從堆棧和靜態(tài)存儲(chǔ)區(qū)的對(duì)象開始,遍歷所有引用,標(biāo)記活得對(duì)象

  對(duì)于標(biāo)記后有兩種處理方式

 ?。?)停止-復(fù)制

  所謂停止,就是停止在運(yùn)行的程序,進(jìn)行垃圾回收

  所謂復(fù)制,就是將活得對(duì)象復(fù)制到另外一個(gè)堆上,以使內(nèi)存更緊湊

  優(yōu)點(diǎn)在于,當(dāng)大塊內(nèi)存釋放時(shí),有利于整個(gè)內(nèi)存的重分配

  有什么問題?

  一、停止,干擾程序的正常運(yùn)行,二,復(fù)制,明顯耗費(fèi)大量時(shí)間,三,如果程序比較穩(wěn)定,垃圾比較少,那么每次重新復(fù)制量是非常大的,非常不合算

  什么時(shí)候啟動(dòng)停止-復(fù)制?

  內(nèi)存數(shù)量較低時(shí),具體多低我也不知道

  (2)清除

  也稱標(biāo)記-清除算法

  也就是將標(biāo)記為非活得對(duì)象釋放,也必須暫停程序運(yùn)行

  優(yōu)點(diǎn)就是在程序比較穩(wěn)定,垃圾比較少的時(shí)候,速度比較快

  有什么問題?

  很顯然停止程序運(yùn)行是一個(gè)問題,只清除也會(huì)造成很對(duì)內(nèi)存碎片。

  為什么這2個(gè)算法都要暫停程序運(yùn)行?

  這是因?yàn)椋绻粫和?,剛才的?biāo)記會(huì)被運(yùn)行的程序弄亂,

  (3)分代收集

  分代收集是利用程序有大量臨時(shí)對(duì)象的特點(diǎn),對(duì)象每被引用一次,代數(shù)就增加,代數(shù)小的小型對(duì)象會(huì)被回收整理,大對(duì)象只會(huì)代數(shù)增加,不會(huì)被整理。

  優(yōu)點(diǎn)在于對(duì)于處理大量臨時(shí)的變量很有幫助

  (4)自適應(yīng)

  jvm會(huì)監(jiān)測(cè)垃圾回收的效率,在(1),(2)算法之間切換。

  3.增量收集,

  增量回收的主要算法還是分代(Young Objects 回收)與Train算法(Mature Object回收),所謂增量回收的關(guān)鍵問題是如何實(shí)現(xiàn)有序的增量回收而不會(huì)導(dǎo)致混亂(引用及其的增加與減少),分代可以逐代回收,Train算法可以逐個(gè)車廂回收,這樣每次一代或每次一廂可以實(shí)現(xiàn)短停頓回收。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java垃圾回收機(jī)制淺析
單例模式討論篇:單例模式與垃圾回收
part5-Java內(nèi)存的回收
深入Java核心 探秘Java垃圾回收機(jī)制
Java垃圾回收機(jī)制與引用類型
二.Java的初始化機(jī)制、垃圾回收機(jī)制和內(nèi)存分配機(jī)制
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服