配置設定過程:
- 編譯器通過逃逸分析,确定對象是在棧上配置設定還是在堆上配置設定。如果是在堆上配置設定,則進入選項2.
- 如果tlab_top + size <= tlab_end,則在在TLAB上直接配置設定對象并增加tlab_top 的值,如果現有的TLAB不足以存放目前對象則3.
- 重新申請一個TLAB,并再次嘗試存放目前對象。如果放不下,則4.
- 在Eden區加鎖(這個區是多線程共享的),如果eden_top + size <= eden_end則将對象存放在Eden區,增加eden_top 的值,如果Eden區不足以存放,則5.
- 執行一次Young GC(minor collection)。
- 經過Young GC之後,如果Eden區任然不足以存放目前對象,則直接配置設定到老年代。
對象不在堆上配置設定的情況有兩種:TLAB和棧上配置設定。
之是以在TLAB(Thread Local Allocation Buffer)上配置設定是因為TLAB是線程私有的,沒有鎖開銷,在Eden上配置設定需要加鎖。
Sun Hotspot JVM為了提升對象記憶體配置設定的效率,對于所建立的線程都會配置設定一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由JVM根據運作的情況計算而得,在TLAB上配置設定對象時不需要加鎖,是以JVM在給線程的對象配置設定記憶體時會盡量的在TLAB上配置設定,在這種情況下JVM中配置設定對象記憶體的性能和C基本是一樣高效的,但如果對象過大的話則仍然是直接使用堆空間配置設定。
關于JVM的一個不錯的部落格:
《聊聊JVM的專欄》
首頁:
raindream
GitHub:
https://github.com/rain-bjtu