Wie viele Bytes belegt ein Array in Java? Angenommen, es handelt sich um eine 64-Bit-Maschine, und es wird auch angenommen, dass ein Array N Elemente enthält, sodass alle diese Elemente für verschiedene Array-Typen 2 * N, 4 * N oder 8 * N Byte belegen würden.
Und eine Vorlesung in Coursera besagt, dass es 2 * N + 24, 4 * N + 24 oder 8 * N + 24 Bytes für ein N-Element-Array belegen würde und die 24 Bytes als Overhead bezeichnet werden, erklärte aber nicht, warum der Overhead ist erforderlich.
Auch Objekte haben Overheads, dh 16 Bytes.
Was genau sind diese Gemeinkosten? Woraus bestehen diese 24/16 Bytes?
Gibt es diese Gemeinkosten auch nur in Java? Wie wäre es mit C, C ++ und Python?
Antworten:
Jedes Java-Objekt verfügt über einen Header, der für die JVM wichtige Informationen enthält. Das wichtigste ist ein Verweis auf die Klasse des Objekts (ein Maschinenwort), und es gibt einige Flags, die vom Garbage Collector verwendet werden, um die Synchronisation zu verwalten (da jedes Objekt synchronisiert werden kann), die ein anderes Maschinenwort aufnimmt (unter Verwendung von Teilwörtern würde) schlecht für die Leistung sein). Das sind also 2 Wörter, das sind 8 Bytes auf 32-Bit-Systemen und 16 Bytes auf 64-Bit. Arrays benötigen zusätzlich ein int-Feld für die Array-Länge, das weitere 4 Bytes beträgt, möglicherweise 8 auf 64-Bit-Systemen.
Wie für andere Sprachen:
C hat keine Objekte, also natürlich keine Objekt-Header - aber möglicherweise einen Header für jedes separat zugewiesene Speicherelement.
In C ++ haben Sie keine Garbage Collection und können keine beliebigen Objekte für die Synchronisierung verwenden. Wenn Sie jedoch Klassen mit überschriebenen Methoden haben, hat jedes Objekt einen Zeiger auf seine vtable, genau wie der Verweis des Java-Objekts auf seine Klasse. Wenn Sie intelligente Zeiger verwenden, die die Speicherbereinigung durchführen, benötigen sie Verwaltungsdaten.
Ich weiß nichts über Python, aber ich bin mir ziemlich sicher, dass es auch einen Verweis auf die Klasse und Informationen zur Haushaltsführung für den Garbage Collector benötigt.
quelle
std::pair<int, float>
ist eine einfache Klasse, die überhaupt keine vtable benötigt. Infolgedessen kann es sehr gut in 8 Bytes passen. Außerdem müssen intelligente Zeiger keine zusätzliche Haushaltsführung hinzufügen. Ein klares Gegenbeispiel iststd::unique_ptr<T>
, dass es normalerweise genauso groß ist wie das RawT*
(unique_ptr macht natürlich keine GC).malloc
zugewiesene Speicherblock benötigt einen Header, derfree
dann verwendet wird.