Das Beispiel in diesem Artikel beschreibt, wie die von einem Java-Objekt belegte Speichermenge berechnet (oder geschätzt) wird. Teilen Sie es als Referenz mit allen. Die spezifische Analyse lautet wie folgt:
Normalerweise sprechen wir im Zusammenhang mit „allgemeinen Fällen“ über die Heap-Speichernutzung. Die folgenden beiden Situationen sind nicht enthalten:
In einigen Fällen legt die JVM das Objekt überhaupt nicht auf dem Heap ab. Beispiel: Im Prinzip existiert ein kleines Thread-lokales Objekt auf dem Stapel, nicht im Heap.
Die von einem Objekt belegte Speichermenge hängt vom aktuellen Status des Objekts ab. Zum Beispiel: ob die Synchronisationssperre des Objekts wirksam ist oder ob das Objekt recycelt wird.
Schauen wir uns zunächst an, wie ein einzelnes Objekt im Heap aussieht.
Im Heap besteht jedes Objekt aus vier Feldern (A, B, C und D). Lassen Sie uns jedes einzelne unten erklären:
A: Objekt-Header, der nur sehr wenige Bytes belegt und Informationen über den aktuellen Status des Objekts ausdrückt.
B: Der von Basistypfeldern belegte Platz (native Felder beziehen sich auf int, boolean, short usw.)
C: Der von Referenztypfeldern belegte Platz (Referenztypfelder beziehen sich auf Referenzen auf andere Objekte, jede Referenz belegt 4 Bytes)
D: Vom Füller eingenommener Platz (was Füller ist, wird später erklärt)
Im Folgenden erklären wir nacheinander A, B, C und D
A: Objektheader
Im Speicher umfasst der von jedem Objekt belegte Gesamtspeicherplatz nicht nur den Speicherplatz, der für innerhalb des Objekts deklarierte Variablen erforderlich ist, sondern auch einige zusätzliche Informationen, wie z. B. Objektkopfzeilen und Füllelemente. Die Funktion des „Objektheaders“ besteht darin, den Instanznamen, die ID und den Instanzstatus eines Objekts aufzuzeichnen (z. B. ob die aktuelle Instanz „erreichbar“ ist oder den Status der aktuellen Sperre usw.).
In der aktuellen JVM-Version (Hotspot) ist die Anzahl der vom „Objektheader“ belegten Bytes wie folgt:
Ein gewöhnliches Objekt, das 8 Bytes belegt
Array, belegt 12 Bytes, einschließlich 8 Bytes + 4 Bytes gewöhnlicher Objekte (Array-Länge)
B: Grundtyp
boolean und byte belegen 1 Byte, char und short belegen 2 Bytes, int und float belegen 4 Bytes, long und double belegen 8 Bytes
C: Referenztyp
Jeder Referenztyp belegt 4 Bytes
D: Füllstoff
In Hotspot wird der von jedem Objekt belegte Gesamtspeicherplatz als Vielfaches von 8 berechnet. Wenn der vom Objekt belegte Gesamtspeicherplatz (Objektkopf + deklarierte Variablen) kleiner als ein Vielfaches von 8 ist, wird er automatisch ausgefüllt. Diese ausgefüllten Räume können jedoch als „Füller“ bezeichnet werden. Schauen wir uns ein konkretes Beispiel an:
Ein leeres Objekt (ohne deklarierte Variablen) belegt 8 Bytes -> der Objektheader belegt 8 Bytes
Eine Klasse, die nur eine Variable vom Typ Boolescher Wert deklariert, belegt 16 Bytes -> Objektkopf (8 Bytes) + Boolescher Wert (1 Bytes) + Füller (7 Bytes)
Eine Klasse, die 8 Variablen vom Typ Boolescher Wert deklariert, belegt 16 Bytes -> Objektheader (8 Bytes) + Boolescher Wert (1 Bytes) * 8
Die obigen Beispiele werden uns helfen, unser Verständnis der Java-Programmierung zu vertiefen.