2013-02-12 95 views
0

如果我有一個對象,並且想要比較其組件的大小,對該對象的大小進行粗略估計,那麼可以這樣做嗎?對象的內存使用情況

該對象具有一個int字段和一個浮點字段。因此,該對象的空間使用量是該對象引用的大小(8)字節+兩個初始值16 + 16的大小,這給我40bytes或25%的額外空間需要。

+0

對象也將引用它的基類。如果它存在於對象中,則引用的大小很重要(不在函數內)。 – Azodious 2013-02-12 10:57:54

+0

由於OOP壓縮(google it),引用的大小大部分是4字節。一個空的Object對象佔用16個字節(或24個字節)的純開銷(監視器,類型標記,各種標誌)。總數再次與8字節的邊界字對齊。 – 2013-02-12 10:59:19

+0

找出最好的方法是通過分配大量對象並比較前後的內存使用情況來進行度量。您還必須照顧GC,並說服自己,結果對於您的JVM和設置是確定性的。 – 2013-02-12 11:00:32

回答

4

檢查對象的近似大小的一種方法是創建該對象的許多實例並檢查前後的內存。爲了得到更準確的數字,您可以使用特定的JVM參數:

-verbose:gc -XX:-UseTLAB 
  • verbose:gc,以確保在測量
  • -XX:-UseTLAB詢問JVM不以塊分配內存的中間沒有發生GC(否則它會提高效率)。關閉該選項可提供更準確和穩定的結果。

然後,您可以通過在分配之前和之後調用Runtime.getRuntime().freeMemory();來監視內存使用情況。

請注意,添加字段不一定會增加內存使用量。例如,對於熱點7 64位,對象在內存中佔用16個字節,但向該對象添加一個int字段不會更改大小(即在該JVM上保持一個int字段的對象也是16字節)。這是由於內存對齊限制。

+1

+1我已經看到'Instrumentation'技術的結果比這個「粗糙」的結果更不準確。例如,它沒有考慮到OOP壓縮。 – 2013-02-12 11:03:58

+0

@MarkoTopolnik這種方法的主要問題是,根據您分配對象的順序,結果可能會有所不同,我從來沒有完全理解。但通過以各種順序進行多次測試,您通常可以獲得準確的結果。 – assylias 2013-02-12 11:07:03

+1

我會將這種方法的另一個優點**稱爲真實問題。一個對象不是'struct',所以誰知道發生了什麼。 – 2013-02-12 11:16:29

0

可以使用java.lang.instrumentation包:

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

它與對象相關聯時可以用來獲取對象大小的實施的具體近似的方法,以及開銷。

答案是謝爾蓋鏈接有一個很好的例子,我將在這裏重新發布,但是你應該已經從他的評論看:

import java.lang.instrument.Instrumentation; 
public class ObjectSizeFetcher { 
private static Instrumentation instrumentation; 

public static void premain(String args, Instrumentation inst) { 
    instrumentation = inst; 
} 

public static long getObjectSize(Object o) { 
    return instrumentation.getObjectSize(o); 
} 
} 

使用getObjectSize:

public class C { 
private int x; 
private int y; 

public static void main(String [] args) { 
    System.out.println(ObjectSizeFetcher.getObjectSize(new C())); 
} 

}