Java對象是怎麼建立的(經過對象的建立,瞭解JVM內存結構)

在代碼層面,咱們經過new關鍵字建立一個對象:html

Object obj=new Object();

而虛擬機中,建立一個對象,則通過了許多環節,JVM的內存結構能夠經過另外一篇文章瞭解:一個「Hello World」理解JVM運行時數據區 ,本文主要基於JVM的內存結構,聊聊對象在JVM中是怎麼建立的:安全

  1. 虛擬機遇到new指令,首先檢查new的參數是否能在方法區中的常量池中定位到一個類的符號引用,而且檢查這個類是否已被加載、解析和初始化過,若是沒有,則先執行類加載機制;(先check是否須要load class,確保類已加載)
  2. 接着,虛擬機將爲對象在堆(Java Heap)中分配一塊內存,對象所需內存的大小在類加載(Class Load)完成後已經能夠肯定。分配的方式主要有2種:指針碰撞(Bump the Pointer)和空閒列表(Free List)
  3. 分配完內存,虛擬機會對這些空間初始化爲零值,這步操做保證了對象的實例字段在Java代碼中能夠不賦初始值就直接使用。
  4. 接着初始化對象頭;對象頭的信息包括:類的元數據信息、哈希碼、GC分代年齡、是否啓用偏向鎖等
  5. 調用<init>方法

關鍵字詞典:併發

指針碰撞:假設Java堆中的內存是規整的,全部已分配的內存都在一邊,空閒的內存在另外一邊,指針的位置在二者中間;當須要分配內存時,只須要將指針向空閒內存區域移動與對象大小相同的距離,這種分配方式叫作「指針碰撞」;Serial、ParNew等帶Campact過程的收集器採用的就是指針碰撞;post

空閒列表:假設Java堆中的內存是不規整的,這些空閒的內存由一個表在維護,當須要分配內存給一個對象時,就會在這張表中查找一個足夠的空閒空間出來分配給該對象,並更新記錄。基於Mark-Sweep的CMS收集器就是使用空閒列表;spa

TLAB:內存的分配涉及了併發時線程安全的問題,所以每一個線程在Java堆中會預先分配一小塊內存做爲該線程的「本地緩衝區」(Thread Local Allocation Buffer),那個線程須要分配內存直接在該線程的TLAB上分配,只有TLAB用完須要分配新的TLAB時,才須要同步鎖定內存。是否啓用TLAB,能夠經過-XX:+/-UseTLAB參數設定;第二、第3步都是在TLAB內完成。線程

相關文章
相關標籤/搜索