1. 程式人生 > >Java 新生代與老年代

Java 新生代與老年代

Java 中的記憶體區域主要有堆和棧兩部分。由於棧是執行緒私有,隨著執行緒的結束而結束,因此垃圾回收主要在堆中進行,堆中幾乎存放了 Java 中所有的物件例項。

堆記憶體模型

堆記憶體分為兩大部分:新生代和老年代,比例關係為1:2。 新生代又分為 Eden、ServivorFrom、ServivorTo 三個區域,比例為8:1:1。ServivorFrom 與 ServivorTo 又被稱為倖存者區。

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

新生代:主要是用來存放新生的物件。

  • Eden:物件被建立的時候首先放到這個區域
  • SurvivorTo:執行垃圾回收時 Eden 與 SurvivorFrom 區域存活的物件被放入到此區域
  • SurvivorFrom:存活的物件被放入 SurvivorTo 之後,清空此區域,SurvivorTo 和 SurvivorFrom 的標記會互換,始終保證一個survivor是空的。
簡單的理解就是有三個籃子,物件預設一開始都放在第一個籃子裡。
  • 當籃子放不下時將存活的物件挑出來放到第二個籃子裡,並將第一個籃子清空。
  • 繼續往第一個籃子中放物件,當籃子又放不下時,將第一和第二個籃子中仍存活的物件挑出來放到第三個籃子,並將第一和第二個籃子清空。
  • 繼續往第一個籃子中放物件,當再次放不下時,將第一和第三個籃子中仍存活的物件放到第二個籃子中,並將第一和第三個籃子清空
  • 重複上述過程,始終保證第二個籃子和第三個籃子中有一個是空的

至於為什麼按照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

獲得了程序的 pid 之後,就可以使用 jmap 工具輸出該程序的堆記憶體使用狀況了(僅摘取部分)。

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

注:PS指Parallel Scavenge並行收集器,是一種吞吐量優先的垃圾回收機制。