垃圾回收個人看

JVM內存區域:

1、虛擬機棧:

    方法執行時的內存模型,是線程私有的,生命週期跟線程相同。方法執行時入棧,方法執行完出棧,出棧相當於清空數據,所以這塊不需要GC。

2、本地方法棧:

    與虛擬機棧功能非常類似,區別在於虛擬機棧爲虛擬機執行java方法時服務,而本地方法棧爲虛擬機執行本地方法時服務,也不需要GC.

3、程序計數器:

    線程獨有,可以看作是當前線程執行的字節碼的指示器。

4、堆:

    對象實例和數組都在堆上分配,GC主要對這兩類數據進行回收。

 

垃圾回收主要方法:

  • 標記清除算法

      先標記出相應的可回收對象,對可回收的對象進行回收,不用移動數據,有內存碎片。

  • 複製算法

      把堆分成兩塊區域A和B,區域A負責分配對象,把存活的對象標記出來複製到B區,最後把A區對象全部清理,這樣就解決了內存碎片的問題了。問題:比如堆分配了500M內存,只有250M可用,移動對象效率低下。

  • 標記整理法

      在標記清除法的基礎上添加了一個整理的過程,將所有的存活對象往一端移動,緊鄰排列,清理另一端的區域,這樣就解決了內存碎片的問題。但是每進行一次垃圾清除都要頻繁移動存活對象,效率低下。

分代收集算法:

      大部分的對象都在很短的時間內被回收了(Minor GC就會被回收),分代收集算法根據對象存活週期的不同將堆分成新生代和老年代,默認比例1:2,新生代分爲Eden區,S0,S1,三者的比例爲8:1:1,新生代的GC稱爲Young GC(也叫Minor GC),老年代發生的GC稱爲Old GC (也叫Full GC)。

1、當Eden區將滿時,觸發Minor GC,存活的對象會被移到S0區;當下一次Minor GC時,會把Eden區和S0(S1)中存活的對象移到S1,同時對象年齡+1,當對象的年齡達到了設定的閾值,則晉升到老年代。

2、如果老年代滿了,會觸發Full GC,Full GC會同時回收新生代和老年代(即對整個堆進行GC),造成挺大的性能開銷。

GC期間,只有垃圾回收器線程在工作,其他工作線程則被掛起。(爲啥GC時工作線程會被掛起?一邊收垃圾,另一邊丟垃圾,收拾不乾淨)

新生代的垃圾回收器:Serial, ParNew, ParallelScavenge

老年代的垃圾回收器:CMS, Serial Old, Parallel Old

同時在新老生代的垃圾回收器:G1

 

如果是運行在桌面環境處於Client模式的,則用Serial + Serial Old 收集器;

如果需要響應時間快,則用ParNew +CMS的搭配;

G1回收器也需要根據吞吐量等要求適當調整相應的JVM參數。

沒有最牛的技術,只有最合適的使用場景。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章