{"id":42684,"date":"2025-04-07T10:50:47","date_gmt":"2025-04-07T08:50:47","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=42684"},"modified":"2026-04-15T15:07:04","modified_gmt":"2026-04-15T13:07:04","slug":"compact-object-headers","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/compact-object-headers\/","title":{"rendered":"Java Compact Object Headers (JEP 519)"},"content":{"rendered":"\n<p>Jedes Java-Objekt hat im Speicher ein den eigentlichen Daten vorangestellten <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/\">Objekt-Header<\/a>. Dieser enth\u00e4lt vor allem den Hash-Code des Objekts und die Information, von welcher Klasse das Objekt eine Instanz ist.<\/p>\n\n\n\n<p>Der Objekt Header ist zum Stand von Java 25 standardm\u00e4\u00dfig 96 Bit (12 Byte) gro\u00df \u2013 oder 128 Bit (16 Byte), wenn <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/#compressed-class-pointers\">Compressed Class Pointers<\/a> ausgeschaltet werden (wozu es aber nahezu keinen Grund gibt \u2013 weshalb diese Option in Java 25 als <em>deprecated<\/em> markiert wurde).<\/p>\n\n\n\n<p>Im Rahmen von <a href=\"https:\/\/wiki.openjdk.org\/spaces\/lilliput\/overview\" target=\"_blank\" rel=\"noreferrer noopener\">Project Lilliput<\/a> t\u00fcfteln die JDK-Entwickler seit vielen Jahren an M\u00f6glichkeiten, um den Header auf insgesamt 64 Bit oder sogar auf 32 Bit zu komprimieren.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"Von Compressed OOP bis Compact Headers: JVM-Interna verst\u00e4ndlich erkl\u00e4rt\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/Cp8Q_fy9UcA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>Im Jahr 2025 war es dann so weit: In <a href=\"https:\/\/www.happycoders.eu\/java\/java-24-features\/#compact-object-headers-experimental-jep-450\">Java 24<\/a> wurden <em>Compact Object Headers<\/em> durch <a href=\"https:\/\/openjdk.org\/jeps\/450\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 450<\/a> als experimentelles Feature eingef\u00fchrt \u2013 und in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/#compact-object-headers-jep-519\">Java 25<\/a> durch <a href=\"https:\/\/openjdk.org\/jeps\/519\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 519<\/a> finalisiert. <em>Compact Object Headers<\/em> erm\u00f6glichen es, den Objekt-Header von 96 Bit auf 64 Bit zu komprimieren und damit die Heap-Gr\u00f6\u00dfe bestehender Anwendungen deutlich zu reduzieren.<\/p>\n\n\n\n<p>In diesem Artikel erf\u00e4hrst du:<\/p>\n\n\n\n<ul class=\"wp-block-list hc-checked-list\">\n<li>Wie funktioniert die Header-Komprimierung?<\/li>\n\n\n\n<li>Warum wird dadurch nicht nur der Speicherbedarf reduziert, sondern auch die Anwendungsperformance erh\u00f6ht?<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"status-quo-vor-compact-object-headers\">Status Quo vor Compact Object Headers<\/h2>\n\n\n\n<p>Eine detaillierte Beschreibung des Aufbaus von Objekt-Headern findest du im <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/\">Hauptartikel \u00fcber Java Object Header<\/a>. Hier das Wichtigste zusammengefasst:<\/p>\n\n\n\n<p>In der Regel besteht der Object Header aus einem 64-Bit \u201eMark Word\u201c und einem 32-Bit \u201eClass Word\u201c. Mark Word und Class Word sind wie folgt aufgebaut:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"217\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-800x217.png\" alt=\"JEP 450: Java Object Header with Mark Word and Class Word\" class=\"wp-image-41735\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-800x217.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-224x61.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-336x91.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-504x137.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-672x182.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-400x109.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-600x163.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-944x256.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3-1200x326.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-java-object-header-mark-word-class-word.v3.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Das <strong>Mark Word<\/strong> enth\u00e4lt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>einen 31-Bit Identity Hash Code (der beim Aufruf von <code>System.identityHashCode(Object)<\/code> zur\u00fcckgegeben wird),<\/li>\n\n\n\n<li>4 Bits, in denen der Garbage Collector das Alter eines Objekts speichert (anhand dessen er entscheidet, wann ein Object von der jungen in die alte Generation verschoben wird),<\/li>\n\n\n\n<li>2 \u201eTag Bits\u201c, die anzeigen, ob das Objekt <em>nicht<\/em>, <em>uncontended<\/em> (ohne wartende Threads) oder <em>contended<\/em> (mit wartenden Threads) gelockt ist.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-info-box uagb-block-76088612 uagb-infobox__content-wrap  uagb-infobox-icon-left uagb-infobox-left uagb-infobox-stacked-mobile uagb-infobox-image-valign-top hc-infobox\"><div class=\"uagb-ifb-icon-wrap\"><svg xmlns=\"https:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z\"><\/path><\/svg><\/div><div class=\"uagb-ifb-content\"><div class=\"uagb-ifb-title-wrap\"><\/div><p class=\"uagb-ifb-desc\">Bei Verwendung des veralteten <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/#legacy-stack-locking\">Legacy Stack Lockings<\/a> wurden im gelockten Zustand die ersten 62 Bit des Mark Words durch einen Pointer auf eine Lock-Datenstruktur ersetzt. Seit <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-23-features\/#Change_LockingMode_default_from_LM_LEGACY_to_LM_LIGHTWEIGHT\">Java 23<\/a> hat das sogenannte <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/#lightweight-locking\">Lightweight Locking<\/a> diesen veralteten Mechanismus abgel\u00f6st.<br><br>Der alte Modus kann aktuell noch durch die VM-Option <code>-XX:LockingMode=1<\/code> reaktiviert werden; er kann allerdings nicht mit <em>Compact Object Headers<\/em> kombiniert werden.<\/p><\/div><\/div>\n\n\n\n<p>Das <strong>Class Word<\/strong> enth\u00e4lt einen 32-Bit-Offset in den maximal 4 GB gro\u00dfen Compressed Class Space, auf die sogenannte <em>Klass<\/em>-Datenstruktur, die alle relevanten Daten \u00fcber die Klasse des Objekts enth\u00e4lt.<\/p>\n\n\n\n<div class=\"wp-block-uagb-info-box uagb-block-cdbef706 uagb-infobox__content-wrap  uagb-infobox-icon-left uagb-infobox-left uagb-infobox-stacked-mobile uagb-infobox-image-valign-top hc-infobox\"><div class=\"uagb-ifb-icon-wrap\"><svg xmlns=\"https:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 128c17.67 0 32 14.33 32 32c0 17.67-14.33 32-32 32S224 177.7 224 160C224 142.3 238.3 128 256 128zM296 384h-80C202.8 384 192 373.3 192 360s10.75-24 24-24h16v-64H224c-13.25 0-24-10.75-24-24S210.8 224 224 224h32c13.25 0 24 10.75 24 24v88h16c13.25 0 24 10.75 24 24S309.3 384 296 384z\"><\/path><\/svg><\/div><div class=\"uagb-ifb-content\"><div class=\"uagb-ifb-title-wrap\"><\/div><p class=\"uagb-ifb-desc\">Wenn <a href=\"https:\/\/www.happycoders.eu\/de\/java\/object-headers-compressed-class-pointers\/#compressed-class-pointers\">Compressed Class Pointers<\/a> mit <code>-XX:-UseCompressedClassPointers<\/code> deaktiviert wurden, dann ist das Class Word 64 Bit gro\u00df und enth\u00e4lt einen <em>unkomprimierten<\/em> Pointer. Die Deaktivierung von Compressed Class Pointers wurde <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/#the-usecompressedclasspointers-option-is-deprecated\">in Java 25 als deprecated markiert<\/a> und kann nicht mit <em>Compact Object Headers<\/em> kombiniert werden.<\/p><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"vom-compressed-class-pointer-zum-compact-object-header\">Vom Compressed Class Pointer zum Compact Object Header<\/h2>\n\n\n\n<p>Wie k\u00f6nnen wir den Objekt-Header weiter komprimieren?<\/p>\n\n\n\n<p>Zun\u00e4chst einmal enth\u00e4lt das Mark Word (wie man oben sieht) aktuell 27 ungenutzte Bits (25 am Anfang und jeweils eines vor und nach den \u201eAge Bits\u201c). Von den 96 Bits des gesamten Object-Headers werden also nur 96 - 27 = 69 Bits ben\u00f6tigt. Um auf 64 Bit zu kommen, m\u00fcssen wir also irgendwie f\u00fcnf Bits einsparen.<\/p>\n\n\n\n<p>Wo k\u00f6nnen wir die hernehmen?<\/p>\n\n\n\n<p>Die JDK-Entwickler haben lange experimentiert, bis sie zu folgender L\u00f6sung kamen (ich habe f\u00fcr eine bessere Darstellung den Ma\u00dfstab ge\u00e4ndert \u2013 die 64 Bit ziehen sich jetzt \u00fcber die gesamte Breite):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"174\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-800x174.png\" alt=\"JEP 450: Compact Object Header\" class=\"wp-image-41736\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-800x174.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-224x49.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-336x73.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-504x110.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-672x146.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-400x87.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-600x131.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-944x205.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2-1200x261.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/11\/jep-450-compact-object-header-java.v2.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Der neue 64 Bit-Header wird nicht mehr in Mark Word und Class Word aufgeteilt, sondern enth\u00e4lt direkt die folgenden Informationen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>einen von 32 Bit auf 22 Bit weiter komprimierten Class Pointer (wird unten erkl\u00e4rt),<\/li>\n\n\n\n<li>den 31-Bit Identity Hash Code (unver\u00e4ndert),<\/li>\n\n\n\n<li>4 f\u00fcr <a href=\"https:\/\/openjdk.org\/projects\/valhalla\/\" target=\"_blank\" rel=\"noopener\">Project Valhalla<\/a> reservierte Bits (neu),<\/li>\n\n\n\n<li>4 Bits f\u00fcr das Alter des Objekts (unver\u00e4ndert),<\/li>\n\n\n\n<li>1 Bit f\u00fcr das sogenannte \u201eSelf Forwarded Tag\u201c (wird unten erkl\u00e4rt),<\/li>\n\n\n\n<li>2 Tag Bits (unver\u00e4ndert).<\/li>\n<\/ul>\n\n\n\n<p>Der Class Pointer wurde also um 10 Bits verkleinert. Da wir nur f\u00fcnf Bits einsparen mussten, stehen nun f\u00fcnf zus\u00e4tzliche Bits zur Verf\u00fcgung. Vier davon wurden f\u00fcr Projekt Valhalla reserviert, und in einem Bit wird das neue \u201eSelf Forwarded Tag\u201c gespeichert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-konnte-der-class-pointer-auf-22-bit-komprimiert-werden\">Wie konnte der Class Pointer auf 22 Bit komprimiert werden?<\/h3>\n\n\n\n<p>Mit den bisherigen 32 Bit konnte jede Position innerhalb des 4 GB gro\u00dfen Compressed Class Space einzeln adressiert werden.<\/p>\n\n\n\n<p>Der Einfachheit halber stelle ich das in der folgenden Grafik mit einem 256 Byte gro\u00dfen Speicherbereich dar:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"245\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-800x245.png\" alt=\"256 Byte gro\u00dfer Speicherbereich\" class=\"wp-image-42706\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-800x245.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-224x69.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-336x103.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-504x154.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-672x206.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-400x123.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-600x184.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-944x289.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-1200x368.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Wie du siehst, brauchen wir die Zahlen 0 bis 255, um jede einzelne Position des Speicherbereichs zu adressieren. Daf\u00fcr brauchen wir einen 8-Bit-Pointer (2<sup>8<\/sup> = 256).<\/p>\n\n\n\n<p>Doch m\u00fcssen wir wirklich jede einzelne Position adressieren k\u00f6nnen? Nein, das m\u00fcssen wir nicht!<\/p>\n\n\n\n<p>Genau wie eine Festplatte (egal ob eine herk\u00f6mmlichen oder eine SSD) in sogenannte (in der Regel 4 KB gro\u00dfe) Bl\u00f6cke aufgeteilt ist, k\u00f6nnen wir auch den Speicherbereich f\u00fcr die Klassendaten in Bl\u00f6cke aufteilen. So muss nicht mehr jedes einzelne Byte adressiert werden, sondern nur noch jeder Block. Und so k\u00f6nnen wir mit deutlich weniger Bits den gleichen Speicherbereich adressieren.<\/p>\n\n\n\n<p>Hier wieder das vereinfachte Beispiel, in dem ich den 256 Byte gro\u00dfen Speicherbereich in 32 Bl\u00f6cke zu je 8 Byte aufteile:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"208\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-800x208.png\" alt=\"256 Byte gro\u00dfer Speicherbereich unterteilt in 8 Byte Bl\u00f6cke\" class=\"wp-image-42707\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-800x208.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-224x58.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-336x87.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-504x131.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-672x175.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-400x104.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-600x156.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-944x245.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks-1200x312.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/memory-section-256-bytes-with-blocks.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Jetzt brauchen wir nur noch die Zahlen 0 bis 31, um den gleichen Speicherbereich zu adressieren. Daf\u00fcr brauchen wir nur noch 5 Bit gro\u00dfe Pointer (2<sup>5<\/sup> = 32). Durch Aufteilung in Bl\u00f6cke konnten wir den Speicherbedarf pro Pointer von 8 Bit auf 5 Bit reduzieren.<\/p>\n\n\n\n<p>Und das funktioniert auch mit dem Speicherbereich, in dem die Klassen-Informationen liegen.<\/p>\n\n\n\n<p>Bei der Verwendung von <em>Compact Object Headers<\/em> wird dieser Speicherbereich in 1.024 (= 2<sup>10<\/sup>) Byte gro\u00dfe Bl\u00f6cke aufgeteilt. Dieser Wert wurde gew\u00e4hlt, da die meisten Klassen zwischen einem halben und einem Kilobyte belegen.<\/p>\n\n\n\n<p>Zur Erinnerung: der Bereich ist 4 GB gro\u00df. Entsprechend ergeben sich 4 \u00d7 1.024 \u00d7 1.024 \u00d7 1.024 \/ 1.024 Bl\u00f6cke, also 4 \u00d7 1.024 \u00d7 1.024, das sind 4.194.304, oder 2<sup>22<\/sup> Bl\u00f6cke. Und diese k\u00f6nnen wir mit 22 Bit adressieren!<\/p>\n\n\n\n<p>Um aus einer 22-Bit-Blocknummer einen Pointer zu machen, m\u00fcssen wir die 32 Bit lediglich um 10 Bit nach links schieben und die hinteren 10 Bit mit Nullen auff\u00fcllen, und damit haben wir wieder einen 32-Bit-Pointer in den 4 GB gro\u00dfen Speicherbereich:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"273\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-600x273.png\" alt=\"22-Bit Blocknummer wird zu einem 32-Bit Class Pointer\" class=\"wp-image-42712\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-600x273.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-224x102.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-336x153.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-504x229.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-672x306.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-400x182.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-800x364.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2-944x430.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-header-class-pointer.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Aufteilung in Bl\u00f6cke f\u00fchrt nun zu einer Fragmentierung bei den Klassendaten. Doch auch das haben die JDK-Developer bedacht: der zwischen den Klassen liegende Speicher kann auch von anderen Datenstrukturen des Metaspace genutzt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"was-ist-das-self-forwarded-tag\">Was ist das \u201eSelf Forwarded Tag\u201c?<\/h3>\n\n\n\n<p>Wenn ein Garbage Collector ein Objekt an eine neue Speicheradresse kopiert, ersetzt er im urspr\u00fcnglichen Objekt die oberen 62 Bit des Mark Words durch einen Pointer auf die neue Speicheradresse und setzt die Tag Bits auf <code>0x11<\/code>. Das urspr\u00fcngliche Mark Word findet er dann an der neuen Adresse. <\/p>\n\n\n\n<p>Wenn der Kopiervorgang fehlschl\u00e4gt, wird das Mark Word durch einen Pointer auf das Objekt selbst ersetzt. Dadurch gehen Identity Hash Code und Alter des Objekts verloren, das scheint aber verschmerzbar zu sein (ich konnte leider keine verl\u00e4ssliche Information dar\u00fcber finden, warum das der Fall ist, werde diesen Absatz aber aktualisieren, sollte ich eine Aussage hierzu finden).<\/p>\n\n\n\n<p>Wenn wir allerdings einen <em>Compact Object Header<\/em> durch eine Selbst-Referenz ersetzen w\u00fcrden, dann w\u00fcrde auch der Class-Pointer verloren gehen. Da dieser essentiell ist, darf ein <em>Compact Object Header<\/em> eben <em>nicht<\/em> durch solch eine Selbst-Referenz ersetzt werden.<\/p>\n\n\n\n<p>Stattdessen wird das neue \u201eSelf Forwarded Tag\u201c-Bit gesetzt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit-zu-compact-object-headers\">Fazit zu Compact Object Headers<\/h2>\n\n\n\n<p><em>Compact Object Headers<\/em> reduzieren den Speicherbedarf eines Java-Programms signifikant, indem die Objekt-Header von 96 Bits (12 Bytes) auf 64 Bit (8 Bytes) reduziert werden.<\/p>\n\n\n\n<p>Und nicht nur das \u2013 dadurch, dass die Objekte kleiner sind, passen auch mehr Objekte in den CPU-Cache. So kommt es zu weniger Cache-Misses \u2013 und das wirkt sich zus\u00e4tzlich positiv auf die Performance aus.<\/p>\n\n\n\n<p>Ab Java 25 k\u00f6nnen <em>Compact Object Headers<\/em> mit folgender VM-Option aktiviert werden:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><code>-XX:+UseCompactObjectHeaders<\/code><\/p>\n\n\n\n<p>In Java 24 befanden sich <em>Compact Object Headers<\/em> noch im experimentellen Stadium und mussten wie folgt aktiviert werden:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><code>-XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"ausblick\">Ausblick<\/h2>\n\n\n\n<p>In einer kommenden Java-Version (welche, ist noch nicht bekannt), werden <em>Compact Object Headers<\/em> standardm\u00e4\u00dfig aktiviert sein (s. <a href=\"https:\/\/openjdk.org\/jeps\/534\" target=\"_blank\" rel=\"noreferrer noopener\">JEP 534 \u201eCompact Object Headers by Default\u201c<\/a>).<\/p>\n\n\n\n<p>Als n\u00e4chstes arbeiten die <em>Project-Lilliput<\/em>-EntwicklerInnen an 4-Byte-Headern \u2013 also einer weiteren Halbierung der Header-Gr\u00f6\u00dfe! F\u00fcr diese weitere Reduzierung m\u00fcssen wir wahrscheinlich Leistungseinbu\u00dfen in Kauf nehmen. Der <a href=\"https:\/\/openjdk.org\/jeps\/8349069\" target=\"_blank\" rel=\"noopener\">JEP-Entwurf \u201e4-byte Object Headers\u201c<\/a> strebt eine maximale Durchsatz- und Latenzreduzierung von 5 % an. Wie die Komprimierung auf vier Byte erreicht werden soll, ist im JEP-Entwurf noch nicht beschrieben.<\/p>\n\n\n\n<p>Hast du <em>Compact Object Headers<\/em> bereits getestet? Hat es die erwarteten Verbesserungen gebracht? Teile deine Erfahrung in den Kommentaren!<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>Du m\u00f6chtest \u00fcber alle neue Java-Features auf dem Laufenden sein? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Durch Compact Object Headers werden Java-Objekt-Header von 96 Bit (12 Byte) auf 64 Bit (8 Byte) komprimiert. Wie funktioniert das ohne Informationsverlust?<\/p>\n","protected":false},"author":1,"featured_media":42719,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"Durch Compact Object Headers werden Java-Objekt-Header von 96 Bit (12 Byte) auf 64 Bit (8 Byte) komprimiert. Wie funktioniert das ohne Informationsverlust?","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"compact object headers","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[],"_seopress_pro_schemas_manual":[],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":9082,"_post_count":0,"footnotes":""},"categories":[64],"tags":[149,165],"class_list":["post-42684","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-core-de","tag-java-fortgeschritten"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/04\/compact-object-headers-hero-image.v2.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Durch Compact Object Headers werden Java-Objekt-Header von 96 Bit (12 Byte) auf 64 Bit (8 Byte) komprimiert. Wie funktioniert das ohne Informationsverlust?","public_identification_id":"137cc891102347a4bacd2264e616dcac","private_identification_id":"a1bc801a59334c9da9cd6d441c3549d9","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=42684"}],"version-history":[{"count":13,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42684\/revisions"}],"predecessor-version":[{"id":56064,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42684\/revisions\/56064"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/42719"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=42684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=42684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=42684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}