Wie groß ist eine Referenzvariable in Java? Kann es berechnet werden?

9

Da Zeiger in C unabhängig von der Größe des Datentyps, auf den sie zeigen, 2 Byte Speichergröße benötigen. Gilt das auch für Java-Referenzen?

Kushagra Thapar
quelle
7
Auf modernen (64-Bit-) Architekturen benötigt C 8 Bytes für einen Zeiger, Java verwendet 4 oder 8, abhängig von der zugrunde liegenden Implementierung (aber es kann alles sein, solange die Semantik erhalten bleibt)
Ratschenfreak
Bei C kommt es auch ganz auf die Implementierung an. Sie können für 32-Bit (einfaches altes x86) kompilieren und 4-Byte-Zeiger erhalten, oder Sie können 64-Bit-Anweisungen und -Register verwenden, aber 4-Byte-Zeiger (x32 ABI)!
Möglicherweise ist das Java-Objektlayout auch aufschlussreich.
Jon Purdy

Antworten:

7

Die Java-Sprachspezifikation sagt nichts darüber aus, wie groß eine Referenz im Speicher ist. Das JLS sagt nicht einmal, dass zur Laufzeit überhaupt eine Referenz vorhanden sein muss . Dem Compiler steht es frei, 42 Gigabyte als Referenz zu verwenden oder diese vollständig zu entfernen, sodass die Größe 0 Byte beträgt. (Tatsächlich sagt die Java-Sprachspezifikation niemals etwas über eine bestimmte Implementierungsstrategie oder -darstellung aus, sondern spezifiziert nur die Syntax und Semantik der Java-Sprachkonstrukte, nicht deren Pragmatik.)

Die meisten typischen Java-Implementierungen implementieren Referenzen einfach als Zeiger, sodass sie dieselbe Größe wie in C haben. Manchmal werden diese Referenzen als OOPs (gewöhnliche Objektzeiger) bezeichnet. Die Oracle Hotspot JVM verfügt beispielsweise über eine Funktion namens CompressedOOPs, mit der einige Referenzen auf 64-Bit-Systemen kleiner als C-Zeiger werden können.

Jörg W Mittag
quelle
5

Aufgrund der -XX:+UseCompressedOops JVM HotSpot-Option betragen die Objektreferenzen 8 Byte.

Ermöglicht die Verwendung komprimierter Zeiger (Objektreferenzen, die als 32-Bit-Offsets anstelle von 64-Bit-Zeigern dargestellt werden) für eine optimierte 64-Bit-Leistung mit Java-Heap-Größen von weniger als 32 GB.

Wir können dies testen, indem wir einen Verweis auf eine leere Klasse hinzufügen und deren Speichernutzung messen. Dies zeigt 24 Bytes, die auf dem Heap verwendet werden. Fügen Sie ein weiteres "Byte" -Primitiv hinzu, messen Sie erneut und Sie sehen 32 Bytes Heap-Nutzung.

Sagar Vaghela
quelle
Was ist "UseCompressedOops"?
Mücke
es ist ein Befehl des jvm-Speichers, oop bedeutet gewöhnlicher Objektzeiger, es erlaubt uns, die Heap-Größe zu erhöhen.
Sagar Vaghela