天天看點

Java 新生代與老年代

Java 中的記憶體區域主要有堆和棧兩部分。由于棧是線程私有,随着線程的結束而結束,是以垃圾回收主要在堆中進行,堆中幾乎存放了 Java 中所有的對象執行個體。

堆記憶體模型

堆記憶體分為兩大部分:新生代和老年代,比例關系為1:2。

新生代分為 Eden、ServivorFrom、ServivorTo 三個區域,比例為8:1:1。ServivorFrom 與 ServivorTo 又被稱為幸存者區。

Java 新生代與老年代

注:圖中用 S0 與 S1 指代 ServivorFrom 與 ServivorTo

新生代:主要是用來存放新生的對象

  • Eden:對象被建立的時候首先放到這個區域
  • SurvivorTo:執行垃圾回收時 Eden 與 SurvivorFrom 區域存活的對象被放入到此區域
  • SurvivorFrom:存活的對象被放入 SurvivorTo 之後,清空此區域,SurvivorTo 和 SurvivorFrom 的标記會互換,始終保證一個survivor是空的。

簡單的了解就是有三個籃子,對象預設一開始都放在第一個籃子裡。

  1. 當籃子放不下時将存活的對象挑出來放到第二個籃子裡,并将第一個籃子清空;
  2. 繼續往第一個籃子中放對象,當籃子又放不下時,将第一和第二個籃子中仍存活的對象挑出來放到第三個籃子,并将第一和第二個籃子清空;
  3. 繼續往第一個籃子中放對象,當再次放不下時,将第一和第三個籃子中仍存活的對象放到第二個籃子中,并将第一和第三個籃子清空
  4. 重複上述過程,始終保證第二個籃子和第三個籃子中有一個是空的

至于為什麼按照 8:1:1 的大小比例來劃分新生代,主要是因為研究表明新生代中的對象98%是朝生夕死的,是以并不需要按照1:1的比例劃分記憶體空間,而是将記憶體分為一塊較大的 Eden 空間和兩塊較小的 Survivor 空間,每次使用 Eden 和其中的一塊 Survivor(可以通過虛拟機參數 -XX:SurvivorRatio 來配置比例)。

這種垃圾收集算法稱為複制算法。新生代中執行的垃圾回收叫做 Minor GC 或 Young GC,每一次 Minor GC 後留下來的對象 age + 1。

老年代:用于存放新生代中經過多次垃圾回收仍然存活的對象,也就是age達到了一定大小;也有可能是新生代配置設定不了記憶體的大對象會直接進入老年代。

檢視JVM記憶體資訊

JDK 中自帶了許多檢視和調試 JVM 的工具,通過這些工具可以很友善的檢視目前線程狀态、記憶體資訊等資料。

例如,我們可以通過指令行工具 jps 擷取目前所有 Java 程序的pid:

C:\>jps -l
15828 thread.Local
8676
10520 org.jetbrains.jps.cmdline.Launcher
8168 sun.tools.jps.Jps      
C:\>jmap -heap 15828
Heap Configuration:
   MaxHeapSize              = 2109734912 (2012.0MB)
   NewSize                  = 44040192 (42.0MB)
   MaxNewSize               = 703070208 (670.5MB)
   OldSize                  = 88080384 (84.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
Heap Usage:
PS Young Generation
Eden Space:
   capacity = 33554432 (32.0MB)
   used     = 5375456 (5.126434326171875MB)
   free     = 28178976 (26.873565673828125MB)
   16.02010726928711% used
From Space:
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
To Space:
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
PS Old Generation
   capacity = 88080384 (84.0MB)
   used     = 0 (0.0MB)
   free     = 88080384 (84.0MB)
   0.0% used