版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。
Java基本資料類型
int 32bit
short 16bit
long 64bit
byte 8bit
char 16bit
float 32bit
double 64bit
Java基本資料類型大小
private static void calSize() {
System.out.println("Integer: " + Integer.SIZE/8); // 4
System.out.println("Short: " + Short.SIZE/8); // 2
System.out.println("Long: " + Long.SIZE/8); // 8
System.out.println("Byte: " + Byte.SIZE/8); // 1
System.out.println("Character: " + Character.SIZE/8); // 2
System.out.println("Float: " + Float.SIZE/8); // 4
System.out.println("Double: " + Double.SIZE/8); // 8
// System.out.println("Boolean: " + Boolean);
}
Java中模拟c中對sizeof的實作
思路:利用java中GC記憶體回收前後的heap size差别,得出每個object的大小
這是一個程式,java中沒有現成的sizeof的實作,原因主要是java中的基本資料類型的大小都是固定的,是以看上去沒有必要用sizeof這個關鍵字。
實作的想法是這樣的:java.lang.Runtime類中有一些簡單的能涉及到記憶體管理的函數:
Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.
long
Returns the amount of free memory in the Java Virtual Machine.
void
Runs the garbage collector.
Returns the runtime object associated with the current Java application.
Returns the maximum amount of memory that the Java virtual machine will attempt to use.
Runs the finalization methods of any objects pending finalization.
使用這些簡單的記憶體通路,可以得到記憶體的一些情況,我們通過建立一個大的某個類的數組,來檢視記憶體用了多少,進而可以求得類的大小。
源碼:
private static void calSize2() {
runGC();
long heap1 = 0;
final int count = 100000;
Object[] objs = new Object[count];
for(int i=-1; i<count; i++) {
Object obj = null;
obj = new Object(); // 8
// obj = new Integer( i ); // 16
// obj = new Short( (short)i ); // 16
// obj = new Long( i ); // 16
// obj = new Byte( (byte)0 ); // 16
// obj = new Character( (char)i ); // 16
// obj = new Float( i ); // 16
// obj = new Double( i ); // 16
// obj = new Boolean( true ); // 16
// obj = new String(); // 40
if(i<0){
obj = null;
runGC();
heap1 = usedMemory(); // before memory size
} else {
objs[i] = obj;
}
}
long heap2 = usedMemory(); // after memory size
final int size = (int)Math.round( (heap2 - heap1)/(double)count );
System.out.println("heap1 = " + heap1 + "; heap2 = " + heap2);
System.out.println("heap2-heap1 = " + (heap2 - heap1) + "; " + objs[0].getClass().getSimpleName() + " size = " + size);
for(int i=0; i<count; i++) {
objs[i] = null;
objs = null;
private static void runGC() {
for(int i=0; i<4; i++) {
long usedMem1 = usedMemory();
long usedMem2 = Long.MAX_VALUE;
for(int j=0; (usedMem1<usedMem2) && (j<500); j++) {
rTime.runFinalization();
rTime.gc();
Thread.yield();
usedMem2 = usedMem1;
usedMem1 = usedMemory();
private static long usedMemory() {
return rTime.totalMemory() - rTime.freeMemory();
注意:Object[] objects = new Object[count];
隻是配置設定了數組空間,沒有配置設定對象的空間。數組中隻有引用而已。
結論:下代碼測試基本對象時,得出的結果象下面:
Object obj = null;
obj = new Object(); // 8
obj = new Integer( i ); // 16
obj = new Short( (short)i ); // 16
obj = new Long( i ); // 16
obj = new Byte( (byte)0 ); // 16
obj = new Character( (char)i ); // 16
obj = new Float( i ); // 16
obj = new Double( i ); // 16
obj = new Boolean( true ); // 16
obj = new String(); // 40
怎麼會這樣呢???解釋如下:
這個例子寫的很好,正好說明了java中基本類型封裝對象所占記憶體的大小.
1.簡單的Object對象要占用8個位元組的記憶體空間,因為每個執行個體都至少必須包含一些最基本操作,比如:wait()/notify(),equals(), hashCode()等
2.使用Integer對象占用了16個位元組,而int占用4個位元組,說了封裝了之後記憶體消耗大了4倍
3.那麼Long看起來比Integer對象應該使用更多空間,結果Long所占的空間也是16個位元組.
那麼就正好說明了JVM的對于基本類型封裝對象的記憶體配置設定的規則是如下:
Object所占記憶體(8個位元組)+最大基本類型(long)所占記憶體(8個位元組) = 16位元組.
JVM強制使用8個位元組作為邊界.
是以所有基本類型封裝對象所占記憶體的大小都是16位元組.
但是還是有差別,比如:
Integer對象雖然占用了16個位元組的記憶體,但是隻是利用了 Object所占記憶體(8個位元組)+int所占記憶體(4個位元組) = 12位元組.
還有4個位元組根本沒有被使用.呵呵,仔細分析了一晚,還是有很多收獲的
<a href="http://download.csdn.net/detail/sunboy_2050/4103419" target="_blank">測試源碼下載下傳</a>
參考推薦:
<a href="http://hi.baidu.com/google1%CF%C2/blog/item/9aa7d026be68263dd507425e.html" target="_blank">關于java中boolean占用位元組的問題</a>
<a href="http://topic.csdn.net/u/20071128/11/19af0938-3700-4bb9-a84d-95a2908f8bbb.html" target="_blank">java中的 boolean 在記憶體中占多少位元組?</a>
本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/sky-heaven/p/5882318.html,如需轉載請自行聯系原作者