Wie kann man Java Garbage Collector davon überzeugen, ausgeführt zu werden, wenn der Arbeitssatz klein ist?
Dies ist eine weitere Frage "Bitte sagen Sie mir, wie Sie den Java-Garbage-Collector zum Ausführen zwingen können". Ich glaube, dass wir in unserer Bewerbung gute Gründe dafür haben.
Hierbei handelt es sich um eine Serveranwendung, die normalerweise ca. 5 Millionen Live-Objekte enthält. Alle 5 Minuten führen wir eine Analyseaufgabe durch, die ~ 60 Sekunden dauert. Wenn ein vollständiger GC ausgelöst wird, während die Analyse ausgeführt wird, gibt es ungefähr 40 Millionen Live-Objekte. Die zusätzlichen 35 Millionen Objekte werden zu Müll, wenn die Analyse abgeschlossen ist. Der Server muss jederzeit auf Anforderungen reagieren (auch während die Analyse ausgeführt wird).
Wir haben festgestellt, dass ein vollständiger GC etwa 1,5 Sekunden dauert, wenn er aufgerufen wird, wenn die Analyse nicht ausgeführt wird, aber etwa 15 Sekunden, während die Analyse ausgeführt wird. Leider ist unser Zuordnungsmuster so, dass in der Regel während der Analyse vollständige GCs ausgelöst werden, obwohl die Analyse nur 20% der Zeit ausgeführt wird. (Jeder dritte oder vierte Analyselauf löst eine vollständige GC aus.)
Ich habe Code hinzugefügt, um das vielverachtete System.gc () kurz vor Beginn eines Analyselaufs aufzurufen, wenn der freie Speicherplatz in der alten Generation unter einem bestimmten Schwellenwert (5 GB) liegt. Der Vorteil war sehr groß: Wir erhalten Pausenzeiten von 1,5 Sekunden anstelle von Pausenzeiten von 15 Sekunden und wir geben mehr Müll für den Handel frei. Manchmal wird der System.gc () -Aufruf jedoch ignoriert und es wird einige Minuten später eine 15-Sekunden-Pause eingelegt, wenn der GC automatisch ausgelöst wird.
Meine Frage lautet also: Können wir den Müllmann noch stärker davon überzeugen, dass er läuft? Wir führen 1.7.0_09-icedtea aus und verwenden den Parallel-GC. Ich möchte entweder (a) eine zuverlässige Möglichkeit, die Garbage Collection manuell zu erzwingen, oder (b) eine Möglichkeit, den Collector so abzustimmen, dass er eine intelligentere automatische Entscheidung trifft. (b) scheint schwierig zu sein, da mir nicht klar ist, wie der Sammler feststellen kann, dass unser Arbeitsset auf diese dramatische Weise variiert.
Ich bin bereit, bei Bedarf auf erheblichen Hackery zurückzugreifen. Dies ist ein ernstes Problem für uns. (Wir könnten die CMS- oder G1-Komprimierungsprogramme als Alternativen in Betracht ziehen, aber ich bin mir der Durchsatzauswirkungen von CMS nicht sicher, und G1 soll sich angesichts der von uns verwendeten Arrays mit großen Bytes schlecht verhalten.)
Nachtrag: In der Produktion haben wir bisher die Erfahrung gemacht, dass System.gc ()meistens löst eine vollständige Speicherbereinigung aus; Zumindest in den Situationen, in denen wir es nennen. (Wir nennen es nur einmal alle 10 bis 30 Minuten, wobei der Haufen etwas, aber nicht vollständig mit Müll gefüllt ist.) Es wäre schön, die Garbage Collection zuverlässiger auslösen zu können, aber es hilft uns die meiste Zeit.