簡體   English   中英

Java和對象,數組和基元類型的精確引用大小

[英]Java and exact reference size for objects, array and primitive types

我想知道在內存中為對象分配的真實空間。

我嘗試用一​​些例子來解釋:使用64位JVM,指針大小應該是8個字節,所以:

  • Object singletest = new Object(); 將占用8個字節來引用Object加上Object的大小
  • Object arraytest = new Object[10]; 將需要8個字節來引用存儲數組的位置加上8 * 10個字節來存儲數組加上每個Object的大小
  • int singleint = new int; 將只占用2個字節,因為int是基本類型
  • int[] arrayint = new int[10]; 將占用8個字節來引用位置,並將10 * 2個字節用於元素

而且,這就是Java允許編寫這樣的代碼的原因:

int[][] doublearray = new int[2][];
int[0][] = new int[5];
int[1][] = new int[10];

真正發生的是數組會像對象一樣產生一個引用(也就是指針),所以在聲明時它並不重要第二維的大小(維度可能不同,它們之間沒有鏈接)。 然后所采用的空間將是:對doublearray (8字節)的引用,第一維只是對第二維的引用,所以其他8字節* 2(第一維尺寸),最后2字節* 5加2字節* 10 。

所以,最后,如果有這樣一個真正的類:

class Test {
   int a, b;
   int getA() {return A};
   void setA(int a) {this.a = a;}
   int getB() {return B};
   void setB(int b) {this.b = b;}
}

當我調用new來實例化時,將使用8字節的指針(或它引用的名稱,因為它是Java)加上2 + 2bytes來將整數存儲到類中。

問題是:我是對的,還是我寫完廢話? 此外,當我沒有實例化一個對象但我只是聲明它時,將分配8個字節以供進一步使用? 如果我指定一個空值怎么辦?

同時對於原始類型我很確定只是聲明它將分配所請求的空間(如果我聲明一個“int i”然后我可以立即調用i ++因為沒有使用引用,只有一部分內存被設置為“0” )。

我沒有聰明的回答在互聯網上搜索...我知道我寫了很多問題,但任何幫助將不勝感激! (也許我不是唯一感興趣的人)

使用64位JVM,指針大小應為8個字節,

實際上它通常是32位,除非你的最大堆大小為32 GB或更多堆。 這是因為Java使用引用而不是指針(並且每個對象都在8字節,而不是1個邊界)

JVM可以根據您使用的JVM以及最大堆大小來更改引用的大小。

Object singletest = new Object(); 將占用8個字節來引用Object加上Object的大小

該對象將使用大約16個字節的堆。 它可能會也可能不會使用4個字節的堆棧,但它可能只使用一個寄存器。

Object arraytest = new Object [10];

這將為標頭使用大約16個字節,加上參考大小的10倍(總共大約56個字節)

int singleint = new int; 將只占用2個字節,因為int是基本類型

int總是32位,你不能創建一個new原語。 從理論上來說,它可能使用4字節的堆棧,也可能只使用寄存器。

int [] arrayint = new int [10]; 將占用8個字節來引用位置,並將10 * 2個字節用於元素

同樣,該對象可能與new Object[10] (56字節)的大小相同

int[][] doublearray = new int[2][];
int[0][] = new int[5];
int[1][] = new int[10];

我不會稱它為doublearray,因為它可能與double[]混淆

然而,對於doublearray和16 + 5 * 4 + 4(對於填充)和16 + 10 * 4,大小可能是大約16 + 2 * 4。

堆上分配的內存與8字節邊界對齊。

我調用new來實例化,將使用8字節的指針(或引用的名稱,因為它是Java)加上2 + 2bytes將整數存儲到類中。

引用位於堆棧上,通常不包括在內。

該對象具有大約16個字節的頭,並且int值占用2 * 4個字節。

當我沒有實例化一個對象,但我只是聲明它

Java不允許您聲明對象,只聲明基元和引用。

如果我指定一個空值怎么辦?

這可能會改變引用的值,但是沒有任何反應。

如果我聲明一個“int i”然后我可以立即調用i ++,因為沒有使用引用,只有一部分內存被設置為“0”

不會使用堆,可能不會使用堆棧(可能是4個字節)。 如果代碼不執行任何操作,JIT編譯器將刪除代碼。

也許我不是唯一感興趣的人

......但是並不害怕問。 ;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM