2010-06-12 5 views
6

Meine Frage bezieht sich auf Speicherabdruck in Java für Klasse ohne Datenelement. Angenommen, in Java habe ich eine Klasse, die kein Datenelement hat und nur Methoden enthält. Wenn ich also eine Instanz einer bestimmten Klasse erstelle, belegt sie dann Speicher im primären Speicher außer dem Objekt-Referenzspeicher?Hat die Klasse ohne Datenelement einen Speicherbedarf in Java?

Antwort

6

Letztendlich kennt jedes Java-Objekt seine Klasse und hat optional ein Synchronisations-Grundelement (obwohl this synthetisch sein kann). Das sind zwei Referenzen, auf die man schwer verzichten kann. Alles andere stammt aus dieser Klasse, also haben Sie einen Kostenrahmen, der mindestens 8 bytes in Java 1.3.1 betrug. Ein Profiler wird Ihnen die aktuellen Kosten mitteilen, wenn Sie sie wirklich brauchen.

+0

+1 für die sehr gute Verbindung – Arne

+1

Eine moderne JVM enthält die Objektüberwachungsdaten in unbenutzten Bits anderer Zeiger, die sie enthält (z. B. die unteren zwei Bits des Klassenzeigers) – dty

+0

@Danny: Es sind drei Bits verfügbar; "Moderne" Speichermanager richten sich auf 8-Byte-Grenzen aus (wenn sie nicht mit Arrays arbeiten, die dichter sind). Und mit "modern" meine ich alles für 10 Jahre oder mehr. –

4

Ja, das tut es, weil zumindest ein "leeres" Objekt zumindest einen Zeiger auf seine Typinformation hat.

+0

Sie haben Recht. Deshalb habe ich in Frage gestellt, außer Objektreferenz/Zeiger. Also abgesehen von Referenz/Punkt hat es einen Speicherbedarf? –

+3

Hängt von der JVM-Implementierung ab. Es wird wahrscheinlich eine Art von Synchronisierungsmechanismus pro Objekt geben oder Merker für den Garbage Collector. Meine beste Schätzung wäre mindestens 8 Bytes pro Objekt Overhead auf einem 32-Bit-Rechner. –

+1

Der Overhead kann für eine 32-Bit-JVM bis zu 16 Byte betragen, abhängig von den JVM-Implementierungsdetails. Die Gemeinkosten umfassen die Größe des primitiven Objekts, die Verbindung zu der Klasse, die Darstellung des primitiven Mutex, die Darstellung des Identitäts-Hash-Codes, die Flags für die Finalisierung und so weiter. –

3

Lassen Sie uns klar sein. Verweise auf Ihr Objekt werden natürlich Raum einnehmen. Aber Ihr Objekt wird auch Platz für seinen "This" -Zeiger (d. H. Damit Sie verschiedene Instanzen unterscheiden können) und auch für die Felder von irgendwelchen Superklassen - z. Objekt - und schließlich was auch immer die internen Datenstrukturen des Heaps haben.

+0

Objekte müssen nicht einen "this" -Zeiger speichern (da der Code den this-Zeiger bereits haben muss, um auf das Objekt zuzugreifen ....) – mikera

+0

Ja, das tun sie. Sie benötigen einen Zeiger auf was in C++ würde die virtuelle Methodentabelle genannt werden. – dty

2

Benchmarking-Speicher ist wegen der verschiedenen Störquellen (wachsende Haufen, GC) schwierig, aber es ist immer noch ein Versuch wert:

public static void main(String[] args) 
{ 
    final int n = 1000000; 

    final Runtime runtime = Runtime.getRuntime(); 

    final Object[] objects = new Object[n]; 

    final long memory0 = runtime.totalMemory() - runtime.freeMemory(); 

    for (int i = 0; i < objects.length; i++) 
    { 
     objects[i] = new Object(); 
    } 

    final long memory1 = runtime.totalMemory() - runtime.freeMemory(); 

    final long memory = memory1 - memory0; 

    System.out.printf(
     "%s %s\n", 
     System.getProperty("java.vm.name"), 
     System.getProperty("java.vm.version")); 

    System.out.printf("%d %d %.1f\n", n, memory, 1.0 * memory/n); 
} 

Java HotSpot (TM) Server VM 14,3-b01 1000000 8000336 8,0

+0

+1 für einen echten Test !! – mikera

Verwandte Themen