請問何時對象分配會不在 TLAB 內分配

Java 對象分配流程

image

咱們這裏不考慮棧上分配,這些會在 JIT 的章節詳細分析,咱們這裏考慮的是沒法棧上分配須要共享的對象git

對於 HotSpot JVM 實現,全部的 GC 算法的實現都是一種對於堆內存的管理,也就是都實現了一種堆的抽象,它們都實現了接口 CollectedHeap。當分配一個對象堆內存空間時,在 CollectedHeap 上首先都會檢查是否啓用了 TLAB,若是啓用了,則會嘗試 TLAB 分配;若是當前線程的 TLAB 大小足夠,那麼從線程當前的 TLAB 中分配;若是不夠,可是當前 TLAB 剩餘空間小於最大浪費空間限制,則從堆上(通常是 Eden 區) 從新申請一個新的 TLAB 進行分配。不然,直接在 TLAB 外進行分配。TLAB 外的分配策略,不一樣的 GC 算法不一樣。例如G1:github

  • 若是是 Humongous 對象(對象在超過 Region 一半大小的時候),直接在 Humongous 區域分配(老年代的連續區域)。
  • 根據 Mutator 情況在當前分配下標的 Region 內分配

TLAB 慢分配與 TLAB 外分配

從新申請一個 TLAB 進行分配,是 TLAB 慢分配,不在 TLAB 分配被稱爲 TLAB 外分配。咱們能夠經過 JFR 來監控 TLAB 慢分配或者 TLAB 外分配事件。也就是jdk.ObjectAllocationOutsideTLABjdk.ObjectAllocationInNewTLAB這兩個事件。算法

jdk.ObjectAllocationOutsideTLABjdk.ObjectAllocationInNewTLAB 這兩個事件在default.jfc中( JFR 默認事件採集配置)是沒有開啓採集的:ide

<event name="jdk.ObjectAllocationInNewTLAB">
  <setting name="enabled">false</setting>
  <setting name="stackTrace">true</setting>
</event>

<event name="jdk.ObjectAllocationOutsideTLAB">
  <setting name="enabled">false</setting>
  <setting name="stackTrace">true</setting>
</event>

通常的,採集這兩個事件,是須要連着堆棧一塊兒採集,可是沒法經過持續時間(由於這個事件沒有持續時間這一律念)限制採集哪些,也就是隻要開啓就是所有采集,因此不建議長期開啓這個採集。而是經過一些其餘的監控項,按照須要,動態開啓這個採集一段時間,以後關閉並 dump 出 JFR 文件用於分析。線程

每日一刷,輕鬆提高技術,斬獲各類offer:code

image

相關文章
相關標籤/搜索