Java基礎知識記錄——創建一個對象涉及的面試題(一)

在這裏插入圖片描述

1.對象的創建過程

和類的創建類似,需要經過半初始化過程。主要經過三步。
main方法中僅有一個語句,就是new一個object,來測試分析。
編譯後的字節碼文件(安裝jclasslib bytecode)如下:

	int a =10;
    public static void main(String[] args) {

        Object obj = new Object();
    }

查看:

0 new #2 <java/lang/Object>
3 dup
4 invokespecial #1 <java/lang/Object.<init>>
7 astore_1
8 return

主要包括三步,先在內存中new,申請一個內存空間,內存空間會對a進行半初始化,賦值爲0,然後再invokespecial,調用類的構造函數,這時候纔會繼續對a賦值爲10,最後,astore_1,將obj指向實例化的內存空間。

2.volatile

  • 1.線程可見性
  • 2.防止指令重排
    先來個測試代碼在這裏插入圖片描述
    程序的意思是,使用flag爲標記,爲false時,暫停新線程。當沒用volatile時,程序會一直執行,停不下來。

另外一個作用是防止指令重拍,設計代碼如下,初始化都爲0,
a=1; b=1;
x=b; y=a;
線程A中跑左邊的賦值,線程B跑右邊的賦值,當xy0時停止。
DCL(雙重鎖檢測)可以結合懶漢模式。

懶漢模式中的應該使用DCL,並且對於實例的修飾必須加上volatile,防止第一個線程拿到鎖,new了一半,被另外的線程拿去使用。

3. 對象在內存中的存儲佈局

在這裏插入圖片描述
對象頭包括三部分,第一部分是identity hashcode,第二部分是gc信息,第三部分是鎖的信息,比較複雜。

在這裏插入圖片描述

4. 對象如何定位

一是句柄池(間接選址),二是直接指針(直接尋址)。
使用句柄池的好處是gc的時候比較穩定,因爲gc的時候會發生對象的複製,使用句柄池則不需要變化t,而直接指針的方式則需要頻繁變化t。使用直接指針的方式是比較快。
在這裏插入圖片描述

5. 對象怎麼分配

關於對象是否會在棧上進行分配,推薦地址:https://blog.csdn.net/o9109003234/article/details/101365108。大概就是兩點,一是逃逸分析,而是標量替換。
原文:

一是逃逸分析:逃逸分析的目的是判斷對象的作用域是否有可能逃逸出函數體。關於逃逸分析的問題可以看我另一篇文章:

二是標量替換:允許將對象打散分配在棧上,比如若一個對象擁有兩個字段,會將這兩個字段視作局部變量進行分配。

只能在server模式下才能啓用逃逸分析,參數-XX:DoEscapeAnalysis啓用逃逸分析,參數-XX:+EliminateAllocations開啓標量替換(默認打開)。Java SE 6u23版本之後,HotSpot中默認就開啓了逃逸分析,可以通過選項-XX:+PrintEscapeAnalysis查看逃逸分析的篩選結果。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章