Ich würde gern messen, wieviel Speicher (in Bytes) bestimmte Objekte im Speicher belegen.
Gibt es Programme mit denen ich mein Programm dahingehend untersuchen kann? Müsste ja eigentlich mit Debugger gehen, aber ich hab's beim Eclipse-JDT-Debugger noch nicht gesehen...
Java eigene Bordmitteln, wie in C++ (size_of war's glaub ich) gibt's ja nicht.
nehmen. Dies ist ein Profiler, der auch direkt in Eclipse integriert werden kann. Über diesen Profiler kannst du dein Programm starten und dir während der laufzeit, zB heapspace, Anzahl von Instanzen bestimmter Objekte, Speicherverbrauch des Programms und noch jede menge mehr anzeigen lassen.
Zuerst einmal: willst du die Größe eines Objektes, oder ein Äquivalent zu size_of()?? size_of in C/C++ wird statisch ausgewertet, kann dir also "nur" die Größe eines Datentyps geben. Wie viel Byte ein String belegt kann es dir nicht sagen (gibt dann "4" oder "8" zurück, je nachdem ob es ein 64 oder 32 Bit Programm werden soll).
Dort gibt es eine Memory Analysis mit der du dir genau die Instanzen der Klassen aufzählen lassen kannst, mit Größe (auch nur statisch).
Willst du nun wirklich die Größe eines Objektes mit seinen Feldern, so kannst du natürlich über Reflections etwas erreichen. Also alle Felder einer Klasse abgrasen, die Größen der einfachen Typen aufaddieren und bei anderen Rekursiv weitermachen. Beispiel:
Vergiss nicht eine Hashtabelle gegen Zyklen einzubauen ;-) Auf Sourceforge gibts ein Projekt, das genau so etwas umsetzen will, scheint aber noch nicht ganz ausgereift: Java.sizeOf
Die VM gibt dir keine Möglichkeit, den Speicherverbrauch einzelner Objekte direkt zu messen.
Was du machen kannst, ist, viele Objekte in einem Array zu speichern und über Methoden in java.lang.Runtime zu gucken, wieviel Speicher die VM gerade reserviert hat und wieviel davon frei ist. Da die VM aber frei ist, mit ihrem Speicher umzugehen, wie sie das für richtig hält, ohne dir was davon erzählen zu müssen, wirst du nie mehr als eine ungenaue Schätzung erhalten.
Und warum willst du das auch wissen? Mich beschleicht das Gefühl, dass hier wieder ein Fall von „premature optimization“ vorliegt, und wir alle wissen, dass das die Wurzel alles Bösen ist. Wenn der Speicher voll ist, gibt’s ’ne freundliche Exception, und du weißt, dass du was ändern musst. Wenn du keine Exception bekommst, ist alles gut.
Mit der "premature optimization" hast du natürlich Recht, aber ich muss halt viele Daten über einen Kapazitätsbegrenzten Kanal (Netzverbindung) schicken und habe ein begrenztes Zeitfenster zur Verfügung nach dessen Ablauf die Daten (fast) wertlos sind und auf Exception warten nicht unbedingt ein guter Lösungsansatz ist. Da ist vorhergehende Abschätzung schon nicht schlecht.
Wenn Du die Objekte ins Netzwerk schicken kannst, dann musst du sie ja auf irgendeine art serialisieren. Das kannst Du natürlich vorher auch im Speicher machen (Stichwort ByteArrayOutputStream) und Dir dann die Größe des Arrays ansehen. Dann bekommst Du zur Laufzeit präzise Informationen über die Größe der zu übertragenen Daten. Wenn genaue Daten nicht erforderlich sind, kannst Du natürlich nur einen Teil serialisieren und dann hochrechnen.
Du kannst dir auch mal den SAP Memory analyzer anschauen. Ist eigentlich ein bisschen ueberdimensioniert fuer deinen Zweck, aber du kannst damit einen Heap dump von zig GB bis ins kleinste Detail analysieren.