Die Objekterstellung in Java kann von null bis Milliarden Zyklen dauern.
- Zero: wenn ein Objekt nicht einem lokalen Bereich, JIT-Compiler nicht entweichen kann eine Zuordnung mit lokalen Variablen als Ergebnis der Verteilung Beseitigung Optimierung ersetzen.
- Milliarden, weil jede Zuordnung möglicherweise (potenziell lange) Garbage Collection auslösen.
habe ich bereits einen High-Level-Überblick über die Zuordnung in HotSpot JVM in this und this Antwort gegeben.
Der gebräuchlichste Weg, um ein Objekt in TLAB umfasst die folgenden Schritte zuzuzuteilen:
- Last
tlab_top
Zeiger (es ist in der Regel ein Register zum Gewinde einheimische auf x64 dedizierte CPU).
- Inkrementieren Sie es um die Größe eines Objekts.
- Vergleichen Sie
tlab_top + object_size
gegen tlab_end
. Wechseln Sie bei Bedarf zum langsamen Pfad.
- Speichern Sie den neuen Wert
tlab_top
. Der vorherige Wert ist die Adresse des neu erstellten Objekts.
- Legen Sie die Standardkopfzeile des Objekts fest.
- Legen Sie das Feld
klass
fest - den Zeiger auf die Klassenmetadaten des Objekts.
- Initialisieren Sie die Restobjektdaten mit Nullen. Selbst ein Objekt ohne Felder kann eine Ausrichtungsauffüllung haben.
Dies alles ist über 10-15 CPU-Anweisungen.
Messen wir die durchschnittliche Zeit einer Objekterstellung mit JMH Benchmark.
package bench;
import org.openjdk.jmh.annotations.Benchmark;
public class Alloc {
@Benchmark
public Object baseline() {
return "Some preallocated object";
}
@Benchmark
public Object newObject() {
return new Object();
}
}
Ergebnisse:
Benchmark Mode Cnt Score Error Units
Alloc.baseline avgt 10 3,428 ± 0,089 ns/op
Alloc.newObject avgt 10 4,505 ± 0,056 ns/op
die Objektzuordnung So, zusammen mit Benchmarking-Overhead nimmt ~ 4,5 ns oder etwa 11 Zyklen auf einem 2,4-GHz-CPU. Im Vergleich zu UUID-Generierungsalgorithmen ist das tatsächlich günstig.
Es dauert weniger als 10 ns. Eine UUID dauert viel, viel länger. –
Die meisten Kosten der Objekterstellung decken nicht die Kosten der Speicherbereinigung zum späteren Wiederherstellen von Speicher oder die Erweiterung der Größe der resultierenden Speichergröße ab, um die Speicherbereinigung durchführbar zu machen, die in der Gesamtressource enthalten sein kann oder nicht Verbrauch, für den Sie tatsächlich berechnet oder interessiert sind. Aber auf jeden Fall werden die meisten UUID-Routinen am Ende ein Objekt erzeugen, das zu Ihnen zurückkehrt und die UUID enthält, so dass die UUID-Lösung nicht billiger sein kann, egal was die Kosten der Objekterstellung sind. – mcdowella
@PeterLawrey, danke für die Zeit; aber würde gerne verstehen, wie viele Schritte es dauert. Und das würde für Millionen Anfragen pro Sekunde passieren. – Shashank