Speicherverbrauch von Objekten im Array

Guten Morgen,

ich habe da mal eine Frage. Wenn ich ein Array mit Objekten meiner Klasse anlegen, wie sieht es mit dem Speicherverbrauch aus? Das Array enthält ja nur Referenzen auf meine Objekte. Die Objekte liegen ja aber dennoch irgendwo im Speicher. Werden jedes mal auch die kompletten Methoden dieser Objekte mit im Speicher abgelegt, oder geschieht dies nur einmal? Schließlich ändern sich die Methoden ja nicht pro Objekt, sondern nur die Eigenschaften/Objektvariabeln. Es wäre ja eine Speicherplatzverschwendung, wenn jede Instanz auch die kompletten Methoden neu mit kopiert. Wie macht Java das intern?

Keine Sorge, das geschieht nur einmal. Für Methoden werden afaik für jede Klasse Sprungtabellen angelegt und zwar pro ClassLoad nur eine. Erbt eine Klasse von einer anderen, wird die komplette Sprungtabelle kopiert und die überschriebenen Methoden neu Referenziert. So hat man jede Methode zumindest nur einmal im Speicher (mit Ausnahme von denen, die beim ClassLoad automatisch geinlined werden).
Auch die Objektvariablen werden (diesmal allerdings pro Instanz - logisch) tabellarisch angelegt, und die (ausdrücklich in Anführungszeichen) “größte Speicherverschwendung” geschieht hier. Für alles unterhalb der Bitbreite int (also boolean, byte, short und char) werden 4 Bytes verwurstet. Ausnahme bilden dabei wieder die Arrays, Array-Elemente dürfen eine Mindestbitbreite von 8 (also 1 Byte) haben.

Speicherverschwendung jein. Performance Gründe hat das. Alle Adresssprünge zu Adressen, die nicht ohne Rest durch die Bitbreite des Prozessor teilbar sind, sind langsam

Ich sag doch „ausdrücklich in Anführungszeichen“. :wink:

Die Java Virtual Maschine ist ziemlich gut darin den Speicher zu verwalten. Genau genommen ist dass ihre Haupaufgabe.

Außerdem ist Java (im Gegensatz zu C++) eine echte Hochsprache, d.h., dass man sich beim Programmieren erstmal nicht um Performaz-Fragen kümmern soll solange man kein spürbares Problem hat.

Der Beste Weg performante Java-Programme zu schreiben ist sich an OO-Regeln zu halten. Ganz vorn dabei sind “Separations of Concens” und “Information Hiding”. Kleine Klassen (bzw. daraus zu erstellende Objekte) und möglichst geringe Sichtbarkeit von Referenzen sorgen z.B. dafür, dass der Garbage Collector weniger Objekte kopieren muss. Dass sorgt wiederum für einen schnelleren GC-Lauf und mehr freien Speicher danach…

bye
TT

Ich danke euch für die ausführlichen Infos.

Allgemein: Alles <(=) int (4 Byte=32 Bit) in Arrays (nicht multidimens.) abzulegen, ist eine gute Idee. Bei Objekten wird die Objektreferenz im Array abgelegt, die ist idR kleiner als das Objekt selbst. Bei Methodenaufrufen wird aber “immer” die Referenz kopiert, deshalb (öffentliche) Klassenvariablen zu verwenden, ist aber nicht gut.
Wo die JVM läuft, ist aber nicht gut, dass man je für ein Bit ein Bit braucht, und wenn doch, dann zB mit ByteArrayOutputStream/BitSet umgehen.
In diesen Java tech docs steht viel mehr dazu drin.
Grüße.

[QUOTE=CyborgBeta]Allgemein: Alles <(=) int (4 Byte=32 Bit) in Arrays (nicht multidimens.) abzulegen, ist eine gute Idee.[/QUOTE]Was bitte willst du denn damit sagen? Dass es etwa besser ist, statt “byte a = 127” “byte[] a = {127}” zu schreiben? Erschreck dich mal nicht, denn so verwurstest du für jedes Byte glatte 4(5?) Bytes mehr. Sinnvoll ists nur, anstatt BooleanArras zu verwenden, auf die Klasse BitSet auszuweichen (IMMER! ;)).

Ach komm schon, byte[] a = { 1(b), 2, 3, 4 }; das benötigt doch nicht so viel tatsächlichen Speicher(-Platz) wie 4 byte-Variablen, auch wenn es Mikrooptimierung ist, oder?

Ich erschrecke mich niemals!!! :wink:

[QUOTE=CyborgBeta]Ach komm schon, byte[] a = { 1(b), 2, 3, 4 }; das benötigt doch nicht so viel tatsächlichen Speicher(-Platz) wie 4 byte-Variablen, auch wenn es Mikrooptimierung ist, oder?[/QUOTE]Arrays haben einen Overhead von 8 Byte. 4 Byte Typreferenz und 4 Byte für die Anzahl an Elementen. Somit kommt dein ByteArray auf 12 Byte. Das sind zwar weniger als 4*4 Byte, der Nachteil ist aber, dass die Variablen nicht mehr eindeutig benannt sind, sondern nunmehr Ziffern haben, die man sich merken müsste. Alternativ kann man diese Variablennamen ja als int-Konstanten (static final) deklarieren, wodurch man letzendlich auch wieder nichts gespart hat.

Ich sag ja, Mikro optimierung, die Benennung kostet Speicherplatz, dafür müssen idexes und Zahlen gerechnet gemerkt werden => leidet die Lesbarkeit (und Performance).

Lasse uns einfach vertragen, Ok?

Edit: Vielleicht auch noch mal der TO melden.

[QUOTE=CyborgBeta]Lasse uns einfach vertragen, Ok?[/QUOTE]Läuft nicht! Ich hab’ mich ja noch gar nicht gestritten! :smiley:

Für den TO schien dieses Thema ja schon durch, von daher sollten wir es gut sein lassen.