衆所周知,Java是一門面向對象的高級編程語言,那麼如今問題來了,對象從哪來呢?有些人會說經過new關鍵字來建立一個對象,說的很好,本篇咱們就來解密在new一個對象的過程當中,JVM都給咱們作了什麼工做。編程
一個對象的誕生一定有一個類,一般咱們都是經過new關鍵字實例化一個類來獲取該類的一個對象,類在加載的過程當中會經歷一系列的檢查,解析,初始化等一系列的過程,咱們會在後面詳細的分步驟進行講解,這裏咱們只關心對象。多線程
下面對象就要被加載到咱們的虛擬機內存的堆內存中,加載到堆內存中也就意味着這個對象須要必定的空間,那麼這個空間走哪來呢?這裏JVM規範給出了兩種狀況:併發
所謂指針碰撞,前提的條件是JVM的堆內存是絕對工整的,中間有一個指針做爲分割空閒空間和已用空間的」三八線「,指針碰撞通常發生在Eden區,跟蹤在Eden建立的最後一個對象,這個對象會被放在Eden的頂部。若是有足夠的空間,對象就會被建立在Eden,而且被放置在頂部,而後將指針向上移動(若是你玩過俄羅斯方塊,你就應該明白,說白了就是一種不可消除絕對規整的俄羅斯方塊),當俄羅斯方塊被堆滿以後,就會觸發一次Minor GC(關於GC的知識,咱們在後面來說解)編程語言
打個比方來講,一個班裏有不少座位,學生必須按照順序來坐,這樣只須要知道最後一個進來的學生坐哪就知道下一個學生坐哪,以及有沒有空位~線程
在單線程的狀況下,咱們這樣使用是沒有什麼問題的,可是若是處於多線程併發的狀況,就會出現分配空間失敗的狀況,打個比方來講,就是把一個位置同時賣給了兩我的,這種狀況勢必就會打架,這種狀況下,咱們能夠採起兩種方法來解決這個問題:3d
CAS(Compare And Swap),關鍵是3個操做數。指針
內存值Vcdn
舊的預期值A對象
要修改的新值Bblog
當且僅當預期值A和內存值V相同時,將內存值V修改成B,不然什麼都不作。
第二種方法,結合咱們上節課說到的TLAB來實現,在分配內存的時候在每一個線程上的TLAB(Thread Local Allocation Buffer)區域進行分配,這裏分配的時候能夠初始化爲零值,這一步操做保證了對象實例字段在Java代碼中不賦值就能夠直接使用。
另外一種狀況是當堆內存不規整的狀況下(學生不要排排坐),JVM會把沒來上課的學生(未使用的內存)記到小本本上,當有新學生(新的對象)來上課的時候,能夠去看本本上的座位圖給學生安排座位~
這個JVM的小本本就叫作空閒列表(Free List)。
到這裏,對於虛擬機,對象就已經找到了本身的座位並落座,下一篇,咱們來介紹一下對象中都有什麼。