Ich habe ein Java Maven Projekt mit ungefähr 800 Quelldateien (einige davon wurden von javacc / JTB generiert), was gut 25 Minuten dauert, um mit javac zu kompilieren.
Wenn ich meine pom.xml-Datei geändert habe, um den Eclipse-Compiler zu verwenden, dauert das Kompilieren etwa 30 Sekunden.
Irgendwelche Vorschläge, warum javac (1.5) so langsam läuft? (Ich möchte nicht permanent zum Eclipse-Compiler wechseln, da das Plugin für Maven mehr als ein kleiner Buggy zu sein scheint.)
Ich habe einen Testfall, der das Problem leicht reproduziert. Der folgende Code generiert eine Anzahl von Quelldateien im Standardpaket. Wenn Sie versuchen, ImplementingClass.java mit javac zu kompilieren, wird es scheinbar unangemessen lange pausieren.
%Vor%Sie erhalten das gleiche Verhalten mit JDK 1.6, einschließlich Update 14, Build 04, mit G1 ändert sich das Verhalten nicht (obwohl G1 scheint wirklich gut zu funktionieren).
Überwachung von javac mit jvisualvm, wiederholte Thread Dumps zeigen den Hauptthread viel Zeit in
%Vor%und durch eine große Anzahl von kurzlebigen Instanzen dieser Klassen:
%Vor% Ich vermute, dass der Code durch com.sun.tools.javac.comp.Check.checkCompatibleConcretes
wackelt, indem er jede Methode mit jeder anderen Methode vergleicht
Die Javadoc-Methode dieser Methode:
%Vor%Es kann sein, dass der Compiler von eclipse diese Überprüfung nicht durchführt oder nicht auf die gleiche Weise durchführt.
Sun hat mir per E-Mail bestätigt, dass dies ein neuer Fehler ist ( 6827648 ) Fehlerdatenbank).
Die Tatsache, dass Sie die generierte Quelle, den massiven Geschwindigkeitsunterschied und StackOverflowError
verwenden, könnte darauf hindeuten, dass eine (oder mehrere) Ihrer Dateien einige Konstrukte enthält, die der javac
parsert stimmt damit nicht überein.
Könnten Sie versuchen, nur Teilmengen Ihres Codes zu kompilieren und zu sehen, ob eine Klasse / Paket den Prozess besonders verlangsamt (wahrscheinlich einer der generierten).
Für den Sun-Compiler starten Sie einen ganzen JVM-Prozess für jede Datei, die Sie kompilieren möchten. Für den Eclipse-Compiler wird nur eine Verbindung zu einem Daemon-Prozess hergestellt. Ich schlage vor, fork auf false zu setzen, obwohl es immer noch nicht ganz so schnell sein kann.
Vielleicht kompiliert der Eclipse-Build nur die modifizierte Quelle. Was passiert, wenn Sie es nach einem Clean in Eclipse kompilieren?
Ich weiß nicht, wie Maven den Compiler aufruft, aber die von Ihnen erwähnten Performance-Zahlen legen nahe, dass javac in seinem eigenen Prozess / VM ausgeführt wird, wie bereits in einer anderen Antwort vorgeschlagen. Da das Starten eines neuen Prozesses / VM für jede Datei, die Sie kompilieren, sehr kostspielig ist, müssen Sie sicherstellen, dass der Compiler so konfiguriert ist, dass er die VM verwendet, die Sie möglicherweise bereits haben. Ich weiß, dass ANT das anbietet, aber ich habe selbst keine Maven benutzt. Angesichts der Tatsache, dass es beliebt ist, bezweifle ich, dass es so ein wichtiges Merkmal fehlt.
Ich denke, es läuft so etwas wie das folgende: Maven gabs javac, JVM-Prozesse für separate Schritte in seinem Lebenszyklus: Maven Build Lebenszyklus
Normalerweise führt Eclipse seine Kompilierung im Hintergrund (bei Save) durch, sodass dieser Schritt der Kompilierungsphase hinzugefügt wird. Wenn es erhebliche Abhängigkeiten gibt, verlieren Sie hier den Durchsatz.
Zusätzlich (abhängig von der mvn-Konfiguration) erhält jede Testmethode ihre eigene JVM. Da die Testdurchführung eine Voraussetzung für die Paketphase ist, ist es möglich, dass Sie Zeit für Ihre JUnit-Testdurchführung verlieren (insbesondere wenn es sich um langsame Tests handelt). Dies ist wahrscheinlich nur dann der Fall, wenn Sie in Ihrem Quellcode viel Testcode haben.
Am wahrscheinlichsten ist, dass Ihre Klasse erhebliche Mengen an Datei-I / O-Operationen durchführt. Es sieht so aus, als ob Ihre Schleife 1000 Mal pro Dateierkennungsereignis ausgeführt wird, was 800 * 1000 = 800.000 PrintStream-Kreationen im Schleifenkörper bedeutet.