小師妹學JVM之 Dirty cards和PLAB

2022-01-10 03:34:08 字數 2217 閱讀 1567

目錄分代垃圾**器在進行minor gc的時候會發生什麼操作呢?有沒有什麼提高效率的手段呢?今天我們和小師妹一起來了解一下垃圾**中的dirty cards和plab

小師妹:f師兄,能再講講分代垃圾收集器中的空間劃分嗎?

分代垃圾**器中的eden,old和survivor space幾個大家應該都很熟悉的分代技術。

young gen被劃分為1個eden space和2個suvivor space。當物件剛剛被建立的時候,是放在eden space。

當eden space滿的時候,就會觸發minor gc。會掃瞄eden space和乙個suvivor space。如果在垃圾**的時候發現eden space中的物件仍然有效,則會將其複製到另外乙個suvivor space。

就這樣不斷的掃瞄,最後經過多次掃瞄發現仍然有效的物件會被放入old gen表示其生命週期比較長,可以減少垃圾**時間。

小師妹:f師兄,minor gc的時候,要將物件從eden複製到suvivor space,從suvivor space中複製到old space。gc是怎麼知道哪些物件是要被**,哪些是不用被**的呢?

小師妹,gc這裡用到了一項叫做dirty cards的技術。

一般來說,新的物件是分配在eden空間的。但是也有些物件是直接分配在old space。

我們知道,gc的掃瞄是從一些根物件開始的,這些root物件包括:正在執行的方法中的本地物件和輸入引數。活動的執行緒,載入類中的static欄位和jni引用。

而這些根物件,一般都是儲存在old space中的。

通常來說old space的空間都會比較大。每次要要找到eden和suvivor space中哪些物件不再被引用,需要掃瞄整個old space肯定是不可取的。

所以jvm在這裡引入了write barrier的技術。hotspot中有兩種write barrier,一種就是今天我們要講的dirty cards,另外一種就是snapshot-at-the-beginning (satb)。 satb通常用在g1垃圾**器中,這裡我們先不做深入的討論。

我們看下上圖中的dirty cards的使用。

dirty cards說起來很簡單,就是每當有程式對引用進行修改的時候,我們都會在乙個dirty cards的空間記錄一下被修改的memory page。

這樣在minor gc的時候,當引用的物件被修改了之後,我們會同步修改對應的dirty cards。這樣每次掃瞄old space的時候,只需要選擇那些標記為dirty cards的物件就可以了,避免了全域性掃瞄。

小師妹,f師兄,你講的好像很有道理的樣子,上次你講到我們在eden空間分配物件的,為了提公升分配的效率,使用了tlab的計算。那麼在物件從eden空間提公升到suvivor space和old space的時候有沒有同樣的技術呢?

當然有的,這個技術就叫做plab( promotion local allocation buffer)。每乙個執行緒在survival space和old space中都乙個plab。在提公升的時候,可以避免多執行緒的競爭,從而提公升效率。

我們可以使用-xx:+alwaystenure 將物件直接從eden space提公升到old space。

我們可以使用-xx:+printoldplab來輸出oldplab的資訊。

小師妹:f師兄,剛剛你講到新分配的物件可以直接在old space,一般什麼物件可以這樣分配呢?

這個很好理解,如果你分配物件大小超過了eden space的大小,是不是就只有old space可以分配物件了?

小師妹:對的,但是一般來說也不會使用這麼大的物件吧。

對的,我們可以通過設定-xx:pretenuresizethreshold=n 來指定物件的大小,如果物件大小大於n,那麼就直接在old space分配。

注意,如果這個物件的大小比tlpb要小,那麼會首先在tlpb中分配。所以使用的時候要注意限制tlpb的大小。

本文已收錄於

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

小甲魚學python之序列

1.序列 列表 元組 字串共同點 利用索引得到值 索引從0開始 通過分片的方式得到元素的集合 很多共同的操作符 list a 把字串轉換為list tuple 把可迭代物件轉換為元組 max 返回集合 序列中的最大值,比較的是ascii碼的值 list reversed list1 reversed...

啟動 jvm 引數小總結

1 啟動某專案 nohup 不結束通話的執行 xms 為 jvm 啟動時分配的記憶體,比如 xms256m,表示分配256m xmx 為 jvm 執行過程中分配的最大記憶體,比如 xms512m,表示jvm程序最多隻能夠占用512m記憶體 xss 為 jvm 啟動的每個執行緒分配的記憶體大小,預設j...

jvm系列文章之jvm 記憶體模型

1.jvm記憶體模型按照執行緒私有與否劃分為兩類,執行緒私有類記憶體 執行緒棧,程式計數器,本地方法棧 和執行緒共享記憶體 堆,方法區or元空間 兩大類 執行緒棧 當類開始執行main方法後,位元組碼執行引擎就會為當前執行緒分配一塊記憶體區域,該區域詳細又可以根據執行的方法為main方法的後續方法分...