jvm 物件記憶體分配方式總結

2021-08-25 21:07:01 字數 1028 閱讀 1426

通常來說關於jvm對於物件的記憶體分配,只要到堆內分配一般就over了,但是在很多人的部落格或者帖子中又說了一些其他的分配,比如棧內分配等等,搞的自己有點眼暈,索性就將jvm記憶體分配的方式統統查了一遍,然後總體上給縷一下。一來是方便自己,權當讀書筆記,二來希望有人能一起討論下。

jvm在記憶體區域中專門劃分出一塊區域來,用於儲存物件的相關資料,這塊區域就叫做堆。堆內的物件資料是各個執行緒所共享的,所以當再堆內建立新的物件時,就要進行鎖操作。而眾所周知鎖操作是比較耗費效能的,因此針對每個執行緒,jvm給它在堆上分配了一塊「自留地」——tlab。tlab全稱是thread local allocation buffer,處於堆記憶體的年輕區,也就是eden這個區域裡。每個執行緒在建立新的物件時,會首先嘗試在自己的tlab裡進行分配,如果成功就返回,失敗了再到共享的eden區里去申請空間。在自己的tlab區域建立物件失敗一般有兩個原因:乙個是物件太大,第二個是自己的tlab區剩餘空間不夠。

這裡就涉及到tlab區域大小的問題了。通常預設的tlab區域大小是eden區域的1%,當然也可以手工進行調整,對應的jvm引數是-xx:tlabwastetargetpercent。

jvm在進行了上面的優化之後,發現建立物件還有可以優化的空間。空間在**?在於物件的生存週期。大部分所建立的物件都無法逃脫一次gc的,其中很多物件更是在乙個執行緒、乃至乙個方法呼叫結束後就over了。針對那些只在一次方法呼叫內生存的物件,jvm通過server方式的優化對其分配策略進行了改進。首先server方式的優化是可以進行複雜的逃逸分析,而後jvm根據逃逸分析的結果,將未逃逸的物件,直接在棧內分配記憶體空間。什麼?棧內??沒錯!!這個分配方式就是棧內分配,當執行緒結束時,棧空間被收回,物件也就直接被**了。由於棧的操作非常快,所以這種對於物件的操作也更加快速。那麼棧內分配時物件資料放在**?這塊我還沒看到相關資料,我分析棧幀有三個區域,區域性變數區、運算元區和剩餘區域,所以物件資料應該是放在剩餘的區域裡,當然這塊是猜測。

以上就是兩種額外的jvm記憶體分配方式。總結起來就是:在server端優化下,如果物件未逃逸,則直接在棧內分配;逃逸之後先嘗試在tlab中分配,失敗後再在堆內分配,還失敗的話,那麼就gc吧。

記憶體分配方式

記憶體分配方式有三種 1 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的 整個執行期間都存在。例如全域性變數,static 變數。2 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函 數執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指...

記憶體分配方式

記憶體分配方式有三種 1 從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個 執行期間都存在。例如全域性變數,static變數。2 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執 行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令...

記憶體分配方式

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其 操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os回 收 注意它與資料結構中的堆是兩回事,分配方...