這是一個程序,java中沒有現成的sizeof的實現,緣由主要是java中的基本數據類型的大小都是固定的,因此看上去沒有必要用sizeof這個關鍵字。google 實現的想法是這樣的:java.lang.Runtime類中有一些簡單的能涉及到內存管理的函數:spa 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..net
long |
freeMemory() Returns the amount of free memory in the Java Virtual Machine. |
void |
gc() Runs the garbage collector. |
static Runtime |
getRuntime() Returns the runtime object associated with the current Java application. |
long |
maxMemory() Returns the maximum amount of memory that the Java virtual machine will attempt to use. |
void |
runFinalization() 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;
- }
- }
-
- runGC();
- 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;
- runGC();
- }
-
- 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字節. Object所佔內存(8個字節) + int所佔內存(4個字節) = 12字節 + 補充4字節 = 16字節. 4. 對齊補充 用於確保對象的總長度爲8字節的整數倍。 JVM中的HotSpot要求對象的總長度必須是8字節的整數倍。因爲對象頭必定是8字節的整數倍,但實例數據部分的長度是任意的,所以須要對齊補充字段確保整個對象的總長度爲8的整數倍。 因此全部基本類型封裝對象所佔內存的大小都是16字節. 也就是說,Integer對象雖然佔用了16個字節的內存,可是隻是利用了12個字節,還有4個字節根本沒有被使用.呵呵,仔細分析了一晚,仍是有不少收穫的 測試源碼下載 參考推薦: 關於java中boolean佔用字節的問題 java中的 boolean 在內存中佔多少字節? Primitive Data Types (SUN 官方文檔) |