{"id":42381,"date":"2024-12-03T17:05:51","date_gmt":"2024-12-03T16:05:51","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=42381"},"modified":"2025-06-12T08:37:25","modified_gmt":"2025-06-12T06:37:25","slug":"ahead-of-time-class-loading-and-linking","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/ahead-of-time-class-loading-and-linking\/","title":{"rendered":"Ahead-of-Time Class Loading &amp; Linking \u2013 Turbo f\u00fcr Java-Programme"},"content":{"rendered":"\n<p>In diesem Artikel erf\u00e4hrst du:<\/p>\n\n\n\n<ul class=\"wp-block-list hc-checked-list\">\n<li>Warum brauchen gro\u00dfe Java-Anwendungen mehrere Sekunden, um zu starten?<\/li>\n\n\n\n<li>Was ist <em>Ahead-of-Time Class Loading &amp; Linking<\/em>, und wie kann es die Startzeit verbessern?<\/li>\n\n\n\n<li>Schritt f\u00fcr Schritt: Wie kann man durch <em>Ahead-of-Time Class Loading &amp; Linking<\/em> den Start einer Anwendung beschleunigen?<\/li>\n\n\n\n<li>Wie unterscheidet sich <em>AoT Class Loading &amp; Linking<\/em> von <em>(App)CDS<\/em>?<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"warum-starten-java-anwendungen-so-langsam\">Warum starten Java-Anwendungen so langsam?<\/h2>\n\n\n\n<p>Java-Anwendungen sind zur Laufzeit extrem flexibel, so k\u00f6nnen Klassen dynamisch geladen und entladen werden, dynamische Compilierung, Optimierung und Deoptimierung macht Java-Programme so schnell wie C-Code (oder schneller), und durch Reflection sind Frameworks wie Jakarta EE, Spring Boot, Quarkus, Helidon, Micronaut, etc. \u00fcberhaupt erst m\u00f6glich.<\/p>\n\n\n\n<p>Doch diese Vorteile haben ihren Preis:<\/p>\n\n\n\n<p>Beim Start einer Anwendung m\u00fcssen Hunderte <em>.jar<\/em>-Dateien entpackt und Tausende <em>.class<\/em>-Dateien in den Speicher geladen, analysiert und verkn\u00fcpft werden. Der statische Initialisierungscode von Klassen muss ausgef\u00fchrt werden, und Frameworks wie Jakarta EE und Spring m\u00fcssen den Code nach Annotationen scannen, Beans instanziieren und Konfigurationscode ausf\u00fchren.<\/p>\n\n\n\n<p>Gro\u00dfe Backend-Anwendungen k\u00f6nnen so mehrere Sekunden oder sogar Minuten ben\u00f6tigen, bis sie vollst\u00e4ndig gestartet sind.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-kann-der-start-von-anwendungen-beschleunigt-werden\">Wie kann der Start von Anwendungen beschleunigt werden?<\/h2>\n\n\n\n<p>Viele der im vorherigen Abschnitt beschriebenen Initialisierungsarbeiten sind bei jedem Anwendungsstart dieselben.<\/p>\n\n\n\n<p>Im Rahmen von <a href=\"https:\/\/openjdk.org\/projects\/leyden\/\" target=\"_blank\" rel=\"noopener\">Project Leyden<\/a> wird daher daran gearbeitet, m\u00f6glichst viele dieser sich immer wiederholenden Aufgaben bereits <em>vor<\/em> dem Start einer Anwendung auszuf\u00fchren.<\/p>\n\n\n\n<p>Durch <a href=\"https:\/\/openjdk.org\/jeps\/483\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 483<\/a> wurden in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-24-features\/#Ahead-of-Time_Class_Loading_Linking_JEP_483\">Java 24 <\/a>die ersten Fr\u00fcchte dieser Arbeit ver\u00f6ffentlicht: Klassen k\u00f6nnen nun nach dem Lesen, Parsen, Laden, und Linken in einer Bin\u00e4rdatei \u2013 dem <em>AOT-Cache<\/em> \u2013 gespeichert werden und sind damit bei zuk\u00fcnftigen Starts derselben Anwendung deutlich schneller in geladenem und gelinkten Zustand verf\u00fcgbar. Die JDK-EntwicklerInnen haben Startzeit-Reduzierungen um bis zu 42 % gemessen.<\/p>\n\n\n\n<p>Durch <a href=\"https:\/\/openjdk.org\/jeps\/514\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 514<\/a>, <em>Ahead-of-Time Command-Line Ergonomics<\/em>, wurde in <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/#ahead-of-time-command-line-ergonomics-jep-514\">Java 25<\/a> die Generierung des AOT-Caches vereinfacht \u2013 statt zwei Schritten muss nur noch einer ausgef\u00fchrt werden.<\/p>\n\n\n\n<p>Durch <a href=\"https:\/\/openjdk.org\/jeps\/514\" target=\"_blank\" rel=\"noopener\">JDK Enhancement Proposal 515<\/a>, <em>Ahead-of-Time Method Profiling<\/em>, wurde \u2013 ebenfalls in Java 25 \u2013 der AOT-Cache um Laufzeitstatistiken \u00fcber Methodenaufrufe erweitert, so dass die JVM direkt nach dem Start mit der Compilierung von Hotspots beginnen kann. Dadurch wurde eine weitere Startzeit-Reduzierungen um 19 % gemessen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wie-funktioniert-ahead-of-time-class-loading-linking\">Wie funktioniert Ahead-of-Time Class Loading &amp; Linking?<\/h2>\n\n\n\n<p>Um den Programmstart durch <em>AoT Class Loading &amp; Linking<\/em> zu beschleunigen, m\u00fcssen wir drei Schritte (bzw. zwei, dazu unten mehr) durchf\u00fchren:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In einem ersten Schritt wird die Anwendung in einem sogenannten <em>Trainingslauf<\/em> gestartet. Dabei analysiert die JVM alle geladenen und gelinkten Klassen und erzeugt eine Konfigurationsdatei mit den relevanten Informationen \u00fcber diese Klassen \u2013 und ab Java 25 zus\u00e4tzlich \u00fcber Methoden-Aufrufstatistiken.<\/li>\n\n\n\n<li>In einem zweiten Schritt wird mit Hilfe dieser Konfigurationsdatei die bin\u00e4re Cache-Datei erzeugt.<\/li>\n\n\n\n<li>Bei jedem weiteren Start der Anwendung wird diese Cache-Datei mit angegeben, und die Anwendung l\u00e4dt die Klassen in geladener und gelinkter Form direkt aus diesem Cache \u2013 und ab Java 25 beginnt sie direkt mit der Optimierung der am h\u00e4ufigsten aufgerufenen Methoden (\u201eHotspots\u201c).<\/li>\n<\/ol>\n\n\n\n<p>Das h\u00f6rt sich komplizierter an als es ist. Im Folgenden f\u00fchre ich dich Schritt f\u00fcr Schritt anhand einer Beispielanwendung durch diese Schritte bis hin zum beschleunigten Start der Anwendung.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"noch-einmal-schritt-fuer-schritt-zum-mitmachen\">Noch einmal Schritt f\u00fcr Schritt zum Mitmachen<\/h3>\n\n\n\n<p>Ich zeige dir in diesem Abschnitt an einer kleinen Anwendung Schritt f\u00fcr Schritt wie <em>Ahead-of-Time Class Loading &amp; Linking<\/em> funktioniert.<\/p>\n\n\n\n<p>Wir benutzen dazu ein ganz einfaches Demo-Programm, das lediglich die aktuelle Zeit anzeigt. <\/p>\n\n\n\n<div class=\"wp-block-columns has-background is-layout-flex wp-container-core-columns-is-layout-f5fea6a2 wp-block-columns-is-layout-flex\" style=\"background-color:#f1f6f9;padding-top:24px;padding-right:24px;padding-bottom:24px;padding-left:24px;font-size:clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.196), 16px);\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:30px\">      \n\t\t\t<div class=\"uagb-icon-wrapper uagb-block-ea1c6094      \"\n\t\t\tstyle=\"\" >\n\t\t\t\t\t\t\t\t\t<span class=\"uagb-svg-wrapper\" \n\t\t\t\t\t aria-label=\"circle-info\"\t\t\t\t\ttabindex=\"0\">\t\t\n\t\t\t\t\t\t\t\t\t\t<svg xmlns=\"https:\/\/www.w3.org\/2000\/svg\" viewBox= \"0 0 512 512\" role=\"graphics-symbol\" aria-hidden=\"false\" aria-label=\"\"><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>\n\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<p>Wir verwenden hier eine <a href=\"https:\/\/www.happycoders.eu\/de\/java\/main-methode\/#compact-source-files-and-instance-main-methods\">kompakte Klassendatei mit einer Instanz-Main-Methode<\/a>. Dadurch m\u00fcssen wir keine Klasse definieren und k\u00f6nnen statt <code>public static void main(String args[])<\/code> einfach <code>void main()<\/code> schreiben.<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Lade dir <a href=\"https:\/\/jdk.java.net\/24\/\">Java 24<\/a> oder ein <a href=\"https:\/\/jdk.java.net\/25\/\" target=\"_blank\" rel=\"noopener\">Early-Access-Build von Java 25<\/a> herunter (<em>Ahead-of-Time Class Loading &amp; Linking<\/em> ist ab Java 24 verf\u00fcgbar, die <code>-XX:AOTCacheOutput<\/code>-Option, mit der wir die ersten zwei Schritte zu einem kombinieren k\u00f6nnen, erst ab Java 25).<\/p>\n\n\n\n<p>Speichere den folgenden Quellcode in der Datei <em>AotTest.java<\/em> ab:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  <span class=\"hljs-keyword\">var<\/span> now = LocalDateTime.now();\n  <span class=\"hljs-keyword\">var<\/span> nowString = now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));\n  System.out.println(<span class=\"hljs-string\">\"Hello, it's \"<\/span> + nowString);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Kompiliere den Code (in Java 24 musst du die Optionen <code>--enable-preview --source 24<\/code> mit angeben, da sich das o. g. Feature <em>Compact Source Files and Instance Main Methods<\/em> in Java 24 noch im Preview-Stadium befindet):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">javac --enable-preview --source 24 AotTest.java<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Erzeuge eine JAR-Datei:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">jar cvf AotTest.jar AotTest.class<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Starte dann den Trainingslauf mit folgendem Aufruf:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">java -XX:AOTMode=record -XX:AOTConfiguration=AotTest.conf \\\n    --enable-preview -cp AotTest.jar AotTest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dadurch wird die Konfigurationsdatei <em>AotTest.conf<\/em> erzeugt. Diese kannst du mit einem Texteditor \u00f6ffnen \u2013 sie enth\u00e4lt eine lange Liste von Klassen und Daten zu diesen Klassen.<\/p>\n\n\n\n<p>Danach erzeugst du mit folgendem Aufruf den Klassen-Cache in der Datei <em>AotTest.aot<\/em> (die Anwendung wird hierbei nicht noch einmal ausgef\u00fchrt):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">java -XX:AOTMode=create -XX:AOTConfiguration=AotTest.conf -XX:AOTCache=AotTest.aot \\\n    --enable-preview -cp AotTest.jar<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-uagb-info-box uagb-block-7bac1066 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\">In Java 25 kannst du Trainingslauf und Erzeugung des Caches (die letzten beiden Schritte vor diesem Info-Block) in einem kombinierten Schritt ausf\u00fchren. Au\u00dferdem ist die Option <code style=\"white-space:nowrap\">--enable-preview<\/code> nicht mehr erforderlich, da <em>Compact Source Files and Instance Main Methods<\/em> in Java 25 finalisiert wurde:<br><br><code>java -XX:AOTCacheOutput=AotTest.aot -cp AotTest.jar AotTest<\/code><\/p><\/div><\/div>\n\n\n\n<p>Und zuletzt startest du die Anwendung und gibst dabei die zu benutztende Cache-Datei an:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">java -XX:AOTCache=AotTest.aot --enable-preview -cp AotTest.jar AotTest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Lass uns nun einmal die Startzeit der Anwendung mit und ohne Cache vergleichen.<\/p>\n\n\n\n<div class=\"wp-block-uagb-info-box uagb-block-7e98a7ab 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\">Im folgenden verwende ich das Linux-Kommando <code>time<\/code>. Unter Windows kannst du das Tool <code>ptime<\/code> verwenden, das du \u00fcber den Package Manager <a href=\"https:\/\/chocolatey.org\/\" target=\"_blank\" rel=\"noopener\">Chocolatey<\/a> mit dem Kommando <code>choco install ptime<\/code> installieren kannt.<\/p><\/div><\/div>\n\n\n\n<p>Zun\u00e4chst ein Aufruf <em>ohne<\/em> Cache:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">time java --enable-preview -cp AotTest.jar AotTest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Bei f\u00fcnf Aufrufen ergab sich bei mir eine mittlere Laufzeit von 0,137 Sekunden.<\/p>\n\n\n\n<p>Und jetzt ein Aufruf <em>mit<\/em> Cache:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">time java -XX:AOTCache=AotTest.aot --enable-preview -cp AotTest.jar AotTest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Hier ergab sich aus f\u00fcnf Aufrufen eine mittlere Laufzeit von 0,086 Sekunden. Das ist eine beeindruckende Leistungssteigerung von 37&nbsp;%, die nah an die von den Entwicklern gemessenen 42&nbsp;% herankommt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"und-was-ist-mit-appcds\">Und was ist mit AppCDS?<\/h2>\n\n\n\n<p>Der aufmerksame Leser wird sich fragen: Was ist der Unterschied zwischen <em>Ahead-of-Time Class Loading &amp; Linking<\/em> und <em>(Application) Class Data Sharing<\/em>?<\/p>\n\n\n\n<p><a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-10-features\/#Class-Data_Sharing\">Class Data Sharing (CDS)<\/a> existiert bereits seit Java 5 und erm\u00f6glicht es, die Klassen des JDK in einem Plattform-spezifischen Bin\u00e4rformat zu speichern, aus dem die Klassen dann deutlich schneller geladen werden k\u00f6nnen als aus <em>.class<\/em>-Dateien.<\/p>\n\n\n\n<p>In Java 10 kam dann <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-10-features\/#Application_Class-Data_Sharing_Schritt_fuer_Schritt\">Application Class Data Sharing (AppCDS)<\/a> hinzu, wodurch nicht mehr nur JDK-Klassen, sondern auch Anwendungsklassen in diesem Bin\u00e4rformat gespeichert werden k\u00f6nnen.<\/p>\n\n\n\n<p>Tats\u00e4chlich baut <em>Ahead-of-Time Class Loading &amp; Linking<\/em> auf <em>(App)CDS<\/em> auf. Falls du dir vorhin die Datei <em>AotTest.conf<\/em> angeschaut hast, ist dir vielleicht aufgefallen, dass der Header sagt, es handle sich um ein \u201eCDS archive dump\u201c.<\/p>\n\n\n\n<p>W\u00e4hrend <em>Class Data Sharing<\/em> die Klassen lediglich liest, parst und dann in einem Bin\u00e4rformat speichert, werden die Klassen beim <em>AoT Class<\/em> <em>Loading &amp; Linking<\/em> zus\u00e4tzlich \u2013 wie der Name schon sagt \u2013 in <code>Class<\/code>-Objekte geladen und gelinkt.<\/p>\n\n\n\n<p>Die Leyden-Entwickler haben beide Mechanismen mit der <a href=\"https:\/\/github.com\/spring-projects\/spring-petclinic\" target=\"_blank\" rel=\"noopener\">Spring PetClinic<\/a> getestet. Durch <em>AppCDS<\/em> wurde die Ladezeit der Anwendung um 33 % beschleunigt und durch <em>AoT Class<\/em> <em>Loading &amp; Linking<\/em> um 42 %. Falls du also bereits <em>AppCDS<\/em> einsetzt, wird die Startzeitverbesserung durch <em>AoT Class Loading &amp; Linking<\/em> nicht mehr ganz so signifikant ausfallen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\">Fazit<\/h2>\n\n\n\n<p>Java ist eine sehr flexible und m\u00e4chtige Sprache, doch diese Flexibilit\u00e4t kann bei gr\u00f6\u00dferen Anwendungen zu Startzeiten im Bereich von mehreren Sekunden bis Minuten f\u00fchren. Beim Start werden u. a. Java-Klassen gelesen, geparst, geladen und gelinkt. <\/p>\n\n\n\n<p>Durch <em>Ahead-of-Time Class Loading &amp; Linking<\/em> k\u00f6nnen diese Schritte vor dem Start der Anwendung einmalig ausgef\u00fchrt werden und dadurch der eigentliche Start der Anwendung \u2013 nach Aussage der Entwickler dieses Features \u2013 um bis zu 42 % beschleunigt werden.<\/p>\n\n\n\n<p>Durch <em>Ahead-of-Time Method Profiling<\/em> werden zudem Statistiken \u00fcber Methodenaufrufe im AOT-Cache gespeichert, so dass direkt nach Start der Anwendung h\u00e4ufig aufgerufene Methoden (\u201eHotspots\u201c) optimiert werden k\u00f6nnen.<\/p>\n\n\n\n<p>Falls du dieses Feature ausprobierst, schreib mir gerne deine Erfahrungen in die Kommentare \u2013 ich bin gespannt auf deine Messwerte und deine Meinung!<\/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>Was ist Ahead-of-Time Class Loading &#038; Linking? Wie funktioniert es, und wie kann es die Startzeit von Java-Programmen um 42 % verbessern? Wie unterscheidet es sich von Application Class Data Loading (AppCDS)?<\/p>\n","protected":false},"author":1,"featured_media":42383,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"","_seopress_titles_desc":"Was ist Ahead-of-Time Class Loading & Linking, und wie kann es die Startzeit von Java-Programmen um 42 % verbessern?","_seopress_robots_index":"","_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":9395,"_post_count":0,"footnotes":""},"categories":[64],"tags":[165],"class_list":["post-42381","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-fortgeschritten"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2024\/12\/ahead-of-time-class-loading-linking.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":"Was ist Ahead-of-Time Class Loading & Linking? Wie funktioniert es, und wie kann es die Startzeit von Java-Programmen um 42 % verbessern? Wie unterscheidet es sich von Application Class Data Loading (AppCDS)?","public_identification_id":"145e9036639048a4abff9a72ab8460df","private_identification_id":"dee7187496404937b2154119d72236a7","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42381","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=42381"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42381\/revisions"}],"predecessor-version":[{"id":52425,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/42381\/revisions\/52425"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/42383"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=42381"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=42381"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=42381"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}