2013-06-02 191 views
9

我想估計一個對象佔用的大小。 要獲得物體的大小,我可以使用如何查找對象的大小(包含包含對象)

要這樣做,我可能會使用Instrumentation.getObjectSize(myObject),但這會給我一個「淺」大小。我想獲取Object的大小,包括它引用的對象的大小。

我的想法是,我需要獲取對象的大小,然後遍歷所有對象的非靜態或基元的字段,並獲取它們指向的對象的大小,並遞歸執行此操作。

當然,我不想計算一個對象大小几次,或者陷入循環,所以我必須記住我們已經計算的大小的對象。

有沒有更快或更標準的方法來做到這一點?

我的代碼如下所示:

public static long getObjectSize(Object obj) 
{ 
    return getObjectSize(obj, new HashSet<Object>()); 
} 

private static long getObjectSize(Object obj, Set<Object> encountered) 
{ 
    if (encountered.contains(obj)) 
    { 
     // if this object was already counted - don't count it again 
     return 0; 
    } 
    else 
    { 
     // remember to not count this object's size again 
     encountered.add(obj); 
    } 
    java.lang.reflect.Field fields[] = obj.getClass().getFields(); 
    long size = Instrumentation.getObjectSize(obj); 
    // itereate through all fields    
    for (Field field : fields) 
    { 
     Class fieldType = field.getType(); 
     // only if the field isn't a primitive 
     if (fieldType != Boolean.class && 
      fieldType != Integer.class && 
      fieldType != Long.class && 
      fieldType != Float.class && 
      fieldType != Character.class && 
      fieldType != Short.class && 
      fieldType != Double.class) 
     { 
      // get the field's value 
      try 
      { 
       Object fieldValue = field.get(obj); 
       size += getObjectSize(obj, encountered); 
      } 
      catch (IllegalAccessException e) {} 
     } 
    } 
    return size; 
} 
+0

可能重複[在Java中,什麼是確定對象大小的最佳方法?](http://stackoverflow.com/questions/52353/in-java-what-is-the-最好的方式來確定大小的對象) – jlordo

+0

https://code.google.com/p/memory-measurer/ https://github.com/twitter/commons/blob/master /src/java/com/twitter/common/objects/ObjectSizeCalculator.java –

回答

5

嘗試序列那麼對象獲得通過序列化生成的字節流的大小。如果你想在持續時知道對象的大小。

public static byte[] serialize(Object obj) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(baos); 
    oos.writeObject(obj); 
    return baos.toByteArray(); 
} 
+0

這是推薦的做法嗎?有替代品嗎? –

+0

我認爲這是最準確的方法,因爲序列化是每個字節的**字節**表示一個對象結構,在最壞的情況下,它會告訴你一個比真實的大一點的大小,但不是較小,這可能會導致尺寸限制問題(最好留出一些空間而不是超過它)。你也可以添加「淺」對象大小(你可以通過instrumentation類得到的大小)來知道一次加載到RAM中的對象的總大小,這當然會使每個基本對象的大小加倍,因爲它們本身就是參考以他們自己的價值。 – arielnmz