2013-06-02 11 views
9

Ich möchte die Größe eines Objekts schätzen. Um die Größe des Objekts zu erhalten, kann ich einfachSo finden Sie die Objektgröße (einschließlich enthaltener Objekte)

verwenden. Dazu könnte ich Instrumentation.getObjectSize(myObject) verwenden, aber das wird mir eine "seichte" Größe geben. Ich möchte die Größe des Objekts einschließlich der Größen der Objekte ermitteln, auf die es verweist.

Mein Gedanke ist, dass ich die Größe des Objekts erhalten muss, dann durch alle Felder des Objekts gehen, die nicht statisch oder primitiv sind und die Größe für die Objekte erhalten, auf die sie zeigen, und dies rekursiv tun.

Natürlich möchte ich eine Objektgröße nicht ein paar Mal zählen oder in einer Schleife stecken bleiben, also muss ich mich an die Objekte erinnern, deren Größe wir bereits gezählt haben.

Gibt es eine schnellere oder eine Standardmethode, dies zu tun?

Mein Code sieht wie folgt aus:

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

möglich Duplikat [In Java, was ist der beste Weg, um die Größe eines Objekts zu bestimmen?] (Http://stackoverflow.com/questions/52353/in-java-what-is-the- best-way-zu-der-Größe-eines-Objekts zu bestimmen) – jlordo

+0

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

Antwort

5

versuchen, das Objekt dann bekommen die Größe des Byte-Strom durch Serialisierung erzeugt serialisiert werden. Wenn Sie die Größe des Objekts wissen möchten, wenn es dauerhaft ist.

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

Ist dies eine empfohlene Praxis? Gibt es Alternativen? –

+0

Ich denke, dies ist die genaueste Methode, da die Serialisierung eine ** Byte pro Byte ** Darstellung einer Objektstruktur ist, und im schlimmsten Fall wird es Ihnen eine Größe ein wenig größer als die echte, aber nicht sagen kleiner, was zu Problemen mit der Größenbeschränkung führen kann (es ist besser, etwas Platz zu lassen als diesen zu überschreiten). Sie können auch die "seichte" Objektgröße (diejenige, die Sie mit der Instrumentierungsklasse erhalten) hinzufügen, um die Gesamtgröße eines einmal in den RAM geladenen Objekts zu kennen. Dies verdoppelt natürlich die Größe für jedes primitive Objekt, da sie selbst die Referenz sind zu ihrem eigenen Wert. – arielnmz