天天看點

深入了解Java虛拟機學習總結(二) 垃圾收集器與記憶體配置設定政策

1、判斷對象是否存活

       引用計數算法:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器++,當引用失效時,計數器--,任何時候計數器為0就是不可能再被使用的。

    算法缺點:難以解決對象之間的互相循環引用問題。(互相引用導緻它們的計數器都不為0),實際虛拟機不是這樣玩的。

2、減少GC開銷的措施,源自:http://blog.csdn.net/zsuguangh/article/details/6429592

        根據上述GC的機制,程式的運作會直接影響系統環境的變化,進而影響GC的觸發。若不針對GC的特點進行設計和編碼,就會出現記憶體駐留等一系列負面影響。為了避免這些影響,基本的原則就是盡可能地減少垃圾和減少GC過程中的開銷。具體措施包括以下幾個方面:

  (1)不要顯式調用System.gc()

  此函數建議JVM進行主GC,雖然隻是建議而非一定,但很多情況下它會觸發主GC,進而增加主GC的頻率,也即增加了間歇性停頓的次數。

  (2)盡量減少臨時對象的使用

  臨時對象在跳出函數調用後,會成為垃圾,少用臨時變量就相當于減少了垃圾的産生,進而延長了出現上述第二個觸發條件出現的時間,減少了主GC的機會。

  (3)對象不用時最好顯式置為Null

  一般而言,為Null的對象都會被作為垃圾處理,是以将不用的對象顯式地設為Null,有利于GC收集器判定垃圾,進而提高了GC的效率。

  (4)盡量使用StringBuffer,而不用String來累加字元串

  由于String是固定長的字元串對象,累加String對象時,并非在一個String對象中擴增,而是重新建立新的String對象,如Str5=Str1+Str2+Str3+Str4,這條語句執行過程中會産生多個垃圾對象,因為對次作“+”操作時都必須建立新的String對象,但這些過渡對象對系統來說是沒有實際意義的,隻會增加更多的垃圾。避免這種情況可以改用StringBuffer來累加字元串,因StringBuffer是可變長的,它在原有基礎上進行擴增,不會産生中間對象。

  (5)能用基本類型如Int,Long,就不用Integer,Long對象

  基本類型變量占用的記憶體資源比相應對象占用的少得多,如果沒有必要,最好使用基本變量。

  (6)盡量少用靜态對象變量

  靜态變量屬于全局變量,不會被GC回收,它們會一直占用記憶體。

  (7)分散對象建立或删除的時間

  集中在短時間内大量建立新對象,特别是大對象,會導緻突然需要大量記憶體,JVM在面臨這種情況時,隻能進行主GC,以回收記憶體或整合記憶體碎片,進而增加主GC的頻率。集中删除對象,道理也是一樣的。它使得突然出現了大量的垃圾對象,空閑空間必然減少,進而大大增加了下一次建立新對象時強制主GC的機會。

面試:

    Java的垃圾回收機制是Java虛拟機提供的能力,用于在空閑時間以不定時的方式動态回收無任何引用的對象占據的記憶體空間。需要注意的是:垃圾回收回收的是無任何引用的對象占據的記憶體空間而不是對象本身,很多公司面試時,都會問這個問題的,70%以上的人回答的含義是回收對象,實際上這是不正确的。System.gc()Runtime.getRuntime().gc() 上面的方法調用時用于顯式通知JVM可以進行一次垃圾回收,但真正垃圾回收機制具體在什麼時間點開始發生動作這同樣是不可預料的,這和搶占式的線程在發生作用時的原理一樣。

繼續閱讀