指針碰撞和空閒列表

對於Java開發來講,在虛擬機內存管理的幫助下,不須要爲每一個新的對象在代碼層面分配內存,回收內存,好比像C語言那樣操做。因此在正常狀況下,內存泄露和內存溢出等問題也不太容易出現。因此要是運行中的程序出現了內存泄露問題,排查仍是有必定困難。安全

Java堆是被全部線程共享的一塊內存區域,主要用於存放對象實例,爲對象分配內存就是把一塊大小肯定的內存從堆內存中劃分出來,一般有指針碰撞和空閒列表兩種實現方式。併發

1.指針碰撞法
假設Java堆中內存時完整的,已分配的內存和空閒內存分別在不一樣的一側,經過一個指針做爲分界點,須要分配內存時,僅僅須要把指針往空閒的一端移動與對象大小相等的距離。使用的GC收集器:Serial、ParNew,適用堆內存規整(即沒有內存碎片)的狀況下。post

2.空閒列表法
事實上,Java堆的內存並非完整的,已分配的內存和空閒內存相互交錯,JVM經過維護一個列表,記錄可用的內存塊信息,當分配操做發生時,從列表中找到一個足夠大的內存塊分配給對象實例,並更新列表上的記錄。使用的GC收集器:CMS,適用堆內存不規整的狀況下。學習

內存分配併發問題線程

在建立對象的時候有一個很重要的問題,就是線程安全,由於在實際開發過程當中,建立對象是很頻繁的事情,做爲虛擬機來講,必需要保證線程是安全的,一般來說,虛擬機採用兩種方式來保證線程安全:指針

  • CAS: CAS 是樂觀鎖的一種實現方式。所謂樂觀鎖就是,每次不加鎖而是假設沒有衝突而去完成某項操做,若是由於衝突失敗就重試,直到成功爲止。虛擬機採用 CAS 配上失敗重試的方式保證更新操做的原子性。
  • TLAB: 爲每個線程預先分配一塊內存,JVM在給線程中的對象分配內存時,首先在TLAB分配,當對象大於TLAB中的剩餘內存或TLAB的內存已用盡時,再採用上述的CAS進行內存分配。

若是想多了,建立一個對象仍是挺麻煩的,須要這麼多步驟,那麼咱們在開發過程當中儘可能非必須的對象建立呢?對象

建立對象有如下幾個要點內存

  1. 類加載機制檢查:JVM首先檢查一個new指令的參數是否能在常量池中定位到一個符號引用,而且檢查該符號引用表明的類是否已被加載、解析和初始化過
  2. 分配內存:把一起肯定大小的內存從Java堆中劃分出來
  3. 初始化零值:對象的實例字段不須要賦初始值也能夠直接使用其默認零值,就是這裏起得做用
  4. 設置對象頭:存儲對象自身的運行時數據,類型指針
  5. 執行<init>:爲對象的字段賦值

學習前人筆記,記錄一下!開發

參考:get

https://www.jianshu.com/p/eaef248b5a2c

http://www.javashuo.com/article/p-dbrhobli-es.html

相關文章
相關標籤/搜索