1. 程式人生 > 其它 >1.java記憶體區域與溢位異常

1.java記憶體區域與溢位異常

執行時資料區,物件的記憶體分佈及記憶體溢位場景的簡單列舉

一,java的執行時資料區分為本地方法棧,虛擬機器棧,程式計數器,堆和方法區

①程式計數器,執行緒私有的,每個執行緒自己單獨維護一個程式計數器,它主要是用於記錄當前執行緒執行的下一條指令的地址

②虛擬機器棧,執行緒私有,每個執行緒自己單獨維護一個虛擬機器棧,主要用於執行緒執行到方法時壓入棧幀

③本地方法棧,和虛擬機器棧基本 一樣,只是執行的是本地方法時壓入的棧幀

④堆,執行緒共享的,主要是用於為為大部分物件的建立提供開闢記憶體的空間

⑤方法區,執行緒共享的,主要是用於存放類元資料資訊,其中包括執行時常量池,class檔案中執行時常量池的資料及符號引用等資訊就是存於此

二,物件在記憶體中的佈局

①建立

首先,檢查下當前要建立的類元資料資訊是否載入到方法區中,如果未載入,則先啟用類載入啟對該類的class檔案進行載入

接著,根據類元資料的資訊,在堆記憶體中開闢對應大小的記憶體空間,這裡開闢的方式有兩種,一種是指標碰撞,就是規整記憶體中,指標的左邊為已使用記憶體,右邊為未使用記憶體,那麼當分配記憶體的時候,只需要將改指標向右移動相應大小的記憶體空間即可,

一種是空閒列表法,是針對不規整的記憶體,那麼虛擬機器會維護一份列表,哪些空間是空閒,哪些空間是已使用的,那麼從空閒列表中找出適合大小的記憶體給予分配,另外,在分配過程中 有可能涉及到併發問題,

也是兩種解決方式,一種是cas+失敗重試,另一種是tlab,thread local allote buffer,即為每個執行緒單獨分配一份當前專門用於分配記憶體的空間,那麼就不會涉及到競爭問題了,只有在分配給當前執行緒的空間不夠 用了,才會涉及到同步問題

然後,初始化空間,賦"零值"

緊接著,設定物件頭

最後,執行建構函式

②記憶體佈局

一個物件在堆中的佈局包括物件頭,例項資料,填充對齊

物件頭 又包括 MarkWord,型別指標及如果是陣列的話還有陣列的長度

③訪問定位

對物件的訪問主要有兩種方法,一種是控制代碼,一種是直接指標

三,溢位場景列舉

①堆溢位,主要是在堆中的物件建立過多,又因為不恰當的引用得不到釋放導致

②棧溢位,那麼有可能就是棧中的棧幀過多或者區域性變量表定義的變數過多

③方法區溢位,主要是載入到方法區中的類元資料過多,且解除安裝不了導致

④直接記憶體溢位,主要是呼叫了開闢堆外記憶體的方法過多導致

本人倡導的講解方式:程式碼示例[學以致用,不僅要知道理論,還要知道理論怎麼付諸實踐], 文字講解[不僅知道要怎麼用,還要知道是怎麼回事], 畫圖講解[有圖有真相,用圖的形式將程式碼嵌入到理論中,整體理解]