欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入java垃圾回收的詳解

 更新時間:2013年06月04日 15:10:04   作者:  
本篇文章是對java垃圾回收進行了詳細的分析介紹,需要的朋友參考下

1.垃圾收集算法的核心思想
Java語言建立了垃圾收集機制,用以跟蹤正在使用的對象和發(fā)現(xiàn)并回收不再使用(引用)的對象。該機制可以有效防范動態(tài)內(nèi)存分配中可能發(fā)生的兩個危險:因內(nèi)存垃圾過多而引發(fā)的內(nèi)存耗盡,以及不恰當?shù)膬?nèi)存釋放所造成的內(nèi)存非法引用。

垃圾收集算法的核心思想是:對虛擬機可用內(nèi)存空間,即堆空間中的對象進行識別,如果對象正在被引用,那么稱其為存活對象,反之,如果對象不再被引用,則為垃圾對象,可以回收其占據(jù)的空間,用于再分配。垃圾收集算法的選擇和垃圾收集系統(tǒng)參數(shù)的合理調節(jié)直接影響著系統(tǒng)性能,因此需要開發(fā)人員做比較深入的了解。

2.觸發(fā)主GC(Garbage Collector)的條件
JVM進行次GC的頻率很高,但因為這種GC占用時間極短,所以對系統(tǒng)產(chǎn)生的影響不大。更值得關注的是主GC的觸發(fā)條件,因為它對系統(tǒng)影響很明顯??偟膩碚f,有兩個條件會觸發(fā)主GC:

(1)當應用程序空閑時,即沒有應用線程在運行時,GC會被調用。因為GC在優(yōu)先級最低的線程中進行,所以當應用忙時,GC線程就不會被調用,但以下條件除外。

(2)Java堆內(nèi)存不足時,GC會被調用。當應用線程在運行,并在運行過程中創(chuàng)建新對象,若這時內(nèi)存空間不足,JVM就會強制地調用GC線程,以便回收內(nèi)存用于新的分配。若GC一次之后仍不能滿足內(nèi)存分配的要求,JVM會再進行兩次GC作進一步的嘗試,若仍無法滿足要求,則 JVM將報“out of memory”的錯誤,Java應用將停止。

由于是否進行主GC由JVM根據(jù)系統(tǒng)環(huán)境決定,而系統(tǒng)環(huán)境在不斷的變化當中,所以主GC的運行具有不確定性,無法預計它何時必然出現(xiàn),但可以確定的是對一個長期運行的應用來說,其主GC是反復進行的。

3.減少GC開銷的措施
根據(jù)上述GC的機制,程序的運行會直接影響系統(tǒng)環(huán)境的變化,從而影響GC的觸發(fā)。若不針對GC的特點進行設計和編碼,就會出現(xiàn)內(nèi)存駐留等一系列負面影響。為了避免這些影響,基本的原則就是盡可能地減少垃圾和減少GC過程中的開銷。具體措施包括以下幾個方面:

(1)不要顯式調用System.gc()
此函數(shù)建議JVM進行主GC,雖然只是建議而非一定,但很多情況下它會觸發(fā)主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數(shù)。這里特別需要說明的是,在代碼中顯示的調用System.gc(),并不一定能夠進行GC,這個我們可以通過finalize()方法進行驗證,即主動調用System.gc(),并不一定每次都調用finalize()方法。finalize()方法的特征是在對象被回收之前, 首先調用finalize()方法。

(2)盡量減少臨時對象的使用
臨時對象在跳出函數(shù)調用后,會成為垃圾,少用臨時變量就相當于減少了垃圾的產(chǎn)生,從而延長了出現(xiàn)上述第二個觸發(fā)條件出現(xiàn)的時間,減少了主GC的機會。

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

(4)盡量使用StringBuffer,而不用String來累加字符串(詳見blog另一篇文章JAVA中String與StringBuffer)
由于String是固定長的字符串對象,累加String對象時,并非在一個String對象中擴增,而是重新創(chuàng)建新的String對象,如 Str5=Str1+Str2+Str3+Str4,這條語句執(zhí)行過程中會產(chǎn)生多個垃圾對象,因為對次作“+”操作時都必須創(chuàng)建新的String對象,但這些過渡對象對系統(tǒng)來說是沒有實際意義的,只會增加更多的垃圾。避免這種情況可以改用StringBuffer來累加字符串,因StringBuffer 是可變長的,它在原有基礎上進行擴增,不會產(chǎn)生中間對象。

(5)能用基本類型如Int,Long,就不用Integer,Long對象
基本類型變量占用的內(nèi)存資源比相應對象占用的少得多,如果沒有必要,最好使用基本變量。什么情況下需要使用Integer?

(6)盡量少用靜態(tài)對象變量
靜態(tài)變量屬于全局變量,不會被GC回收,它們會一直占用內(nèi)存。

(7)分散對象創(chuàng)建或刪除的時間
集中在短時間內(nèi)大量創(chuàng)建新對象,特別是大對象,會導致突然需要大量內(nèi)存,JVM在面臨這種情況時,只能進行主GC,以回收內(nèi)存或整合內(nèi)存碎片, 從而增加主GC的頻率。集中刪除對象,道理也是一樣的。它使得突然出現(xiàn)了大量的垃圾對象,空閑空間必然減少,從而大大增加了下一次創(chuàng)建新對象時強制主GC 的機會。

4.垃圾回收算法
(1)引用計數(shù)收集器
引用計數(shù)是垃圾收集的早期策略。在這種方法中,堆中每一個對象都有一個引用計數(shù)。當一個對象被創(chuàng)建了,并且指向該對象的引用被分配給一個變量,這個對象的引用計數(shù)被設置為1。比如新建一個對象A a=new A();然后a被分配給另外一個變量b,也就是b=a;那么對象a的引用計數(shù)+1。當任何其他變量被賦值為對這個對象的引用時,計數(shù)加1。當一個對象的引用超過生存期或者被設置一個新的值時,對象的引用計數(shù)減1,比如令b=c,則a的引用計數(shù)-1。任何引用計數(shù)為0的對象可以被當做垃圾收集。當一個對象被垃圾收集的時候,它引用的任何對象計數(shù)減1。在這種方法中,一個對象被垃圾收集后可能導致后續(xù)其他對象的垃圾收集行動。比如A a=new A();b=a;當b被垃圾回收以后,a的引用計數(shù)變?yōu)?,這樣導致a也被垃圾回收。

方法的好處:引用計數(shù)收集器可以很快執(zhí)行,交織在程序的運行之中。這個提醒對于程序不能被長時間打斷的實時環(huán)境很有利。

方法的壞處:引用計數(shù)無法檢測出循環(huán)(即兩個或者更多的對象互相引用)。循環(huán)的例子如,父對象有一個子對象的引用,子對象又反過來引用父對象。這樣對象用戶都不可能計數(shù)為0,就算它們已經(jīng)無法被執(zhí)行程序的根對象觸及。還有一個壞處就是,每次引用計數(shù)的增加或者減少都帶來額外的開銷。

(2)追蹤收集器
垃圾檢測通常通過建立一個根對象的集合并且檢查從這些根對象開始的可觸及性來實現(xiàn)。如果正在執(zhí)行的程序可以訪問到的根對象和某個對象之間存在引用路徑,這個對象就是可觸及的。對于程序來說,根對象總是可以訪問的。從這些根對象開始,任何可以被觸及的對象都是被認為是“活動”的對象。無法被觸及的對象被認為是垃圾,因為它們不在影響程序的未來執(zhí)行。

跟蹤收集器是追蹤從根結點開始的對象引用圖。在追蹤過程中遇到的對象以某手方式打上標記??偟膩碚f,要么在對象本身上設置標記,要么用一個獨立的位圖來設置標記。當追蹤結束時,未被標記的對象就是無法觸及的,從而可以被收集。

基本的追蹤算法被稱作“標記并清除”。這個名字指出垃圾手機的兩個階段。在標記階段,垃圾收集器遍歷引用樹,標記每一個遇到的對象。在清除階段,未被標記的對象被釋放,釋放對象后獲得的內(nèi)存被返回到正在執(zhí)行的程序。在Java虛擬機中,清除步驟必須包括對象的終結。

相關文章

  • 詳解spring cloud config整合gitlab搭建分布式的配置中心

    詳解spring cloud config整合gitlab搭建分布式的配置中心

    這篇文章主要介紹了詳解spring cloud config整合gitlab搭建分布式的配置中心,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Josephus環(huán)的四種解法(約瑟夫環(huán))基于java詳解

    Josephus環(huán)的四種解法(約瑟夫環(huán))基于java詳解

    這篇文章主要介紹了Josephus環(huán)的四種解法(約瑟夫環(huán))基于java詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • Java 發(fā)送http請求上傳文件功能實例

    Java 發(fā)送http請求上傳文件功能實例

    本文通過實例代碼給大家介紹了Java 發(fā)送http請求上傳文件功能,需要的朋友參考下吧
    2017-06-06
  • Java class文件格式之特殊字符串_動力節(jié)點Java學院整理

    Java class文件格式之特殊字符串_動力節(jié)點Java學院整理

    特殊字符串出現(xiàn)在class文件中的常量池中,本著循序漸進和減少跨度的原則, 首先把class文件中的特殊字符串做一個詳細的介紹, 然后再回過頭來繼續(xù)講解常量池,對java class 文件格式相關知識感興趣的的朋友一起學習吧
    2017-06-06
  • Mybatis之RowBounds分頁原理詳解

    Mybatis之RowBounds分頁原理詳解

    這篇文章主要介紹了Mybatis之RowBounds分頁原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • spring boot devtools在Idea中實現(xiàn)熱部署方法

    spring boot devtools在Idea中實現(xiàn)熱部署方法

    這篇文章主要介紹了spring boot devtools在Idea中實現(xiàn)熱部署方法及注意要點,需要的朋友可以參考下
    2018-02-02
  • javaweb實現(xiàn)注冊登錄頁面

    javaweb實現(xiàn)注冊登錄頁面

    這篇文章主要為大家詳細介紹了javaweb實現(xiàn)注冊登錄頁面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 詳解Java弱引用(WeakReference)的理解與使用

    詳解Java弱引用(WeakReference)的理解與使用

    這篇文章主要介紹了Java弱引用(WeakReference)的理解與使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • 常見JavaWeb安全問題和解決方案

    常見JavaWeb安全問題和解決方案

    這篇文章主要介紹了常見JavaWeb安全問題和解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java正則表達式之split()方法實例詳解

    Java正則表達式之split()方法實例詳解

    這篇文章主要介紹了Java正則表達式之split()方法,結合實例形式較為詳細的分析了split方法的功能、使用方法及相關注意事項,需要的朋友可以參考下
    2017-03-03

最新評論