2017-06-10 3 views
0

Angenommen, ich bin in einer 64-Bit-Maschine kompiliert ein C-Programm mit gcc. Ich nehme an, dass sizeof(int) 8 Bytes ist und sizeof(char) 1 Byte ist.Speicherausrichtung der Java-Klassen

Aufgrund der Speicherausrichtung, die folgenden Struktur:

struct example{ 
    int a; 
    char c; 
} 

hat tatsächlich nicht mit einer Größe von 9 Bytes, aber 16 (zweimal sizeof(int)), so daß sowohl seine Anfangs- und Endadressen bei Vielfachen von sein können die Wortgröße (angenommen hier 8 Bytes).

Ich habe mich gefragt, wie groß die folgende Klasse in Java 8 sein würde:

class Node { 
    int val; 
    Node left, right; 
    boolean flag; 
} 

Ich bin im Grunde nicht sicher, ob wir bei Vielfachen von 8 oder 4 Byte ausrichten würden.

Antwort

2

Tatsächlich spezifizieren weder die JLS noch die JVMS Speicherausrichtungsregeln. Es ist plattformspezifisch. Die einzigen Möglichkeiten, um sicher zu wissen, wie Felder im Speicher ausgerichtet sind, sind:

  • Lesen Sie den JVM-Quellcode.
  • Untersuchen Sie den systemeigenen Code, der vom JIT-Compiler ausgegeben wird.
  • (möglicherweise) machen Sie einige böse Tricks mit Unsafe oder JNI/JNA-Code, um die Abstraktionsschichten zu durchbrechen, die entworfen sind, um Ihren Java-Code von Abhängigkeiten von der physischen Darstellung zu isolieren.

  • UPDATE: use "jol" Toolkit - siehe @ ZhekaKozlov Antwort

Die einfachere Frage, wie viele Bytes verwendet werden, um ein Objekt repräsentieren kann mit der Instrumentation.getObjectSize Methode beantwortet werden:

Aber beachten Sie, dass thi s gibt eine Schätzung der Größe, und die Spezifikation für die Methode ermöglicht eine Menge "wackeln Raum" auf, was das eigentlich bedeutet.

+0

Darüber hinaus ist die Größe eines Typs nicht die wahre Größe des Typs. Die Größe eines Typs umfasst mehr als die bloßen Elemente. Sie haben Methoden, Konstruktoren, Header, Membertypen mit eigenem Overhead, das 'class' Literal, ... und die Instanzen können in der Größe variieren, von null Bytes bis zu einem Register oder zwei bis zu ein paar Bytes im Stack die vollständige berechnete Größe auf dem Heap einschließlich der zusammengesetzten Instanzen, abhängig von den Laufzeitbedingungen. –

2

Sie können jol verwenden, um das genaue Layout von Objekten zu kennen. Dies ist die Ausgabe des Programms für die Node-Klasse (auf Oracle JDK 1.8.0_121 64 Bit):

# Running 64-bit HotSpot VM. 
# Using compressed oop with 3-bit shift. 
# Using compressed klass with 3-bit shift. 
# Objects are 8 bytes aligned. 
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 

org.example.Node object internals: 
OFFSET SIZE TYPE DESCRIPTION     VALUE 
    0  4   (object header)    01 00 00 00 (00000001 00000000 00000000 00000000) (1) 
    4  4   (object header)    00 00 00 00 (00000000 00000000 00000000 00000000) (0) 
    8  4   (object header)    70 22 01 f8 (01110000 00100010 00000001 11111000) (-134143376) 
    12  4  int Node.val      0 
    16  1 boolean Node.flag      false 
    17  3   (alignment/padding gap)  N/A 
    20  4 Node Node.left      null 
    24  4 Node Node.right      null 
    28  4   (loss due to the next object alignment) 
Instance size: 32 bytes 
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total 

Also, die Ausrichtung ist 8 Byte. Für 32-Bit-JVM wären es 4 Bytes.

Hinweis, dies ist plattformspezifisch. Sie sollten sich nicht sehr auf diese Informationen verlassen.

+0

Ah, die Ausrichtung Informationen ist genau dort. Großartig, danke! – Jason

Verwandte Themen