Einstellung -XX: + DisableExplicitGC in der Produktion: Was könnte schief gehen?
gerade hatten wir eine Besprechung, um einige performance-Probleme in eine web-Anwendung, die verwendet wird, zu berechnen Versicherung Preise. Die Berechnungen implementiert sind, in ein C/C++-Modul, das verwendet wird, in andere software-Pakete. Verfügbar als webservice, ein Java-wrapper implementiert wurde, stellt eine XML-basierte Schnittstelle und ruft die C/C++-Modul über JNI.
Messungen zeigten, dass mehrere Sekunden verbrachte er auf jede Berechnung innerhalb der Java-Teil. Also meine erste recomodation zu ermöglichen, garbage collection logging in der VM. Wir konnten sehen, dass viele um-die-Welt voller GCs gemacht wurden. Reden, die Entwickler der java-Teil erzählte uns, Sie habe eine System.gc()
bei mehreren Gelegenheiten ", um sicherzustellen, dass der Speicher nach der Freigabe verwenden".
OK, ich werde nicht näher auf diese Aussage irgendwie weiter... 😉
Wir dann fügte genannten -XX:+DisableExplicitGC
zu den VMs Argumente und reran die tests. Dies machte etwa 5 Sekunden pro Berechnung.
Da wir Sie nicht ändern Sie den code durch Strippen alle diejenigen System.gc()
ruft an dieser Stelle in unserer release-Prozess, wir denken über das hinzufügen von -XX:+DisableExplicitGC
in der Produktion, bis eine neue Jar-Datei erstellt werden kann.
Ist jetzt die Frage: könnte es da irgendein Risiko dabei? Über die einzige Sache, die ich denken kann, ist tomcat mit System.gc()
intern, wenn die Versetzung, aber das ist nur eine Vermutung. Gibt es irgendwelche anderen Gefahren vor?
InformationsquelleAutor der Frage Axel | 2012-10-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie nicht allein in der Festsetzung stop-the-world-GC-Ereignisse durch die Einstellung der
-XX:+DisableExplicitGC
Flagge. Leider (und trotz der HAFTUNGSAUSSCHLÜSSE in der Dokumentation), viele Entwickler entscheiden, Sie wissen es besser als die JVM beim sammeln, Speicher-und Stell genau diese Art von Problem.Ich kenne viele Fälle, wo die
-XX:+DisableExplicitGC
verbessert die Produktionsumgebung und keine Fälle, in denen gab es keine negativen Nebenwirkungen.Die sichere Sache zu tun ist, führen Sie Ihre aktuellen Produktions-code, unter Last, mit der das flag in einer stress-test-Umgebung, und führen Sie eine normale QA Zyklus.
Wenn Sie das nicht können, würde ich vorschlagen, dass das Risiko der Einstellung die Flagge ist weniger als die Kosten der nicht-Einstellung in den meisten Fällen.
InformationsquelleAutor der Antwort Eric J.
Ich habe wrestling mit diesem gleichen Problem, und basierend auf all den Informationen, die ich habe finden können, es scheint definitiv ein gewisses Risiko. Pro die Kommentare auf dem ursprünglichen post von @millimoose, sowie https://bugs.openjdk.java.net/browse/JDK-6200079 , es scheint, dass die Festlegung von -XX:+DisableExplicitGC wäre eine schlechte Idee, wenn der NIO-direkter Puffer verwendet werden. Es scheint, dass Sie verwendet werden in der internen Implementierung der Websphere 8.5-app-server, die wir verwenden. Hier ist der stack-trace, ich war in der Lage zu erfassen, während des Debuggens:
Nur, was genau die vollen Auswirkungen sind von der Einstellung-XX:+DisableExplicitGC wenn NIO direct byte buffer verwendet wird, ist nicht ganz klar, um mich noch (tut das einführen eines memory-leak?), aber zumindest scheint zu sein, ein gewisses Risiko gibt es. Wenn man eine app anderen server als Websphere stellen Sie sicher, dass der app-server selbst nicht aufrufen System.gc() via NIO, bevor Sie es deaktivieren. Ich habe eine Frage, hoffentlich bekommen einige Aufklärung über die exakten Auswirkungen auf die NIO-Bibliotheken hier: Auswirkungen der Einstellung -XX:+DisableExplicitGC wenn NIO direct buffer werden verwendet
Übrigens, Websphere, scheint auch manuell aufrufen System.gc() mehrere Male während des boot-Prozesses, in der Regel zweimal innerhalb der ersten paar Sekunden nach dem app-server gestartet wird, und ein drittes mal innerhalb der ersten 1-2 Minuten (vielleicht, wenn die Anwendung bereitgestellt wird). In unserem Fall ist dies, warum wir begonnen, die Untersuchung in den ersten Platz, als es scheint, dass alle das System.gc() Aufrufe kommen direkt aus dem app-server, und nie aus unserer Anwendung code.
Es sollte auch darauf hingewiesen werden, dass neben der NIO-Bibliotheken, die JDK-internen Implementierung der RMI distributed garbage collection auch Anrufe System.gc():
Unerklärliche System.gc() Aufrufe durch Remote Method Invocation
System.gc() Aufrufe von core-APIs
Ob enabling " - XX:+DisableExplicitGC wird auch verheerend mit RMI DGC ist auch ein wenig unklar für mich. Die einzige Referenz, die ich habe finden können, sogar Adressen, das ist die erste Referenz oben, die Staaten
Dass "in den meisten Fällen' qualifier klingt schrecklich, wischi-waschi, um mich so wieder, wie es scheint, gibt es zumindest einige Risiko ist nur das abschalten aller System.gc() aufruft, und Sie wären besser dran, die Festsetzung der Anrufe in Ihrem code, wenn überhaupt möglich, und nur ausschalten, Sie komplett auszuschalten, als eine Letzte resort.
InformationsquelleAutor der Antwort rscarter
Wenn Sie
-XX:+DisableExplicitGC
und die Verwendung von CMS, die Sie möglicherweise verwenden möchten-XX:+CMSClassUnloadingEnabled
als auch begrenzen ein weiterer Grund für die volle GCs (d.h. der PermGen voll). Andere als die, ich hatte noch keine Probleme mit der option, zwar hab ich wechselte mit-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
weil meine einzige Grund für die explizite GCs war, RMI, nicht der code der Anwendung.InformationsquelleAutor der Antwort Frank Pavageau