1、創(chuàng)建對象的幾種方式
????????①new 對象
????????②反射
????????③對象的復制
????????④反序列化
2、創(chuàng)建對象流程
- 先看看常量池里面有沒有,如果有,就用常量池的
- 看這個類有沒有被加載過,如果沒有,就執(zhí)行類加載以及類的初始化。(對象的大小,在類加載的時候就確定了)。
- 對象在堆內存里面的劃分(2種):
指針碰撞:假設Java堆中內存是絕對規(guī)整的,所有被使用過的內存都被放在一 邊,空閑的內存被放在另一邊,中間放著一個指針作為分界點的指示器,那所分配內存就僅僅是把那 個指針向空閑空間方向挪動一段與對象大小相等的距離,這種分配方式稱為“指針碰撞”(Bump The Pointer)。
空閑列表:但如果Java堆中的內存并不是規(guī)整的,已被使用的內存和空閑的內存相互交錯在一起,那 就沒有辦法簡單地進行指針碰撞了,虛擬機就必須維護一個列表,記錄上哪些內存塊是可用的,在分 配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄
選擇哪種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用 的垃圾收集器是否帶有空間壓縮整理(Compact)的能力決定。因此,當使用Serial、ParNew等帶壓縮 整理過程的收集器時,系統(tǒng)采用的分配算法是指針碰撞,既簡單又高效;而當使用CMS這種基于清除 (Sweep)算法的收集器時,理論上就只能采用較為復雜的空閑列表來分配內存。 - jvm構造對象頭信息,new指令之后會接著執(zhí)行構造方法。
對象頭存放內容:例如這個對象是哪個類的實例、如何才能找到類的元數(shù)據(jù)信息、對象的哈希碼(實際上對象的哈希碼會延后到真正調用Object::hashCode()方法時才 計算)、對象的GC分代年齡等信息。
3、什么時候加鎖
并發(fā)情況下,需要考慮步驟是不是原子性(動作不能再繼續(xù)被拆分了,讀是原子性,寫是原子性,讀加寫就不是原子性),如果不是原子性,一定要加鎖。文章來源:http://www.zghlxwxcb.cn/news/detail-610192.html
4、解決并發(fā)下的安全問題
對象創(chuàng)建在虛擬機中是非常頻繁的行為,即使僅僅修改一個指針所指向的位置,在并發(fā)情況下也并不是線程安全的,可能出現(xiàn)正在給對象 A分配內存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內存的情況。解決這個問題有兩種可選方案:文章來源地址http://www.zghlxwxcb.cn/news/detail-610192.html
- 一種是對分配內存空間的動作進行同步處理——實際上虛擬機是采用CAS配上失敗 重試的方式保證更新操作的原子性;
- 另外一種是把內存分配的動作按照線程劃分在不同的空間之中進 行,即每個線程在Java堆中預先分配一小塊內存,稱為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB),哪個線程要分配內存,就在哪個線程的本地緩沖區(qū)中分配,只有本地緩沖區(qū)用完 了,分配新的緩存區(qū)時才需要同步鎖定。虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數(shù)來 設定。
到了這里,關于深入理解JVM:Java使用new創(chuàng)建對象的流程的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!