Wir haben eine Anwendung, die in der Regel ~ 20 JVMs besteht und wir verteilen Batch-Jobs an sie. Die 20 JVMs laufen im selben Betriebssystem. Bevor man einen Stapeljob an einen von ihnen schickt, ist es schwer zu sagen, wie lang und wie groß der Job ist. Es könnte 1 Minute oder mehrere Stunden dauern. Der Speicherverbrauch variiert ähnlich.Garbage Collection für mehrere VMs
Bisher funktionierte das gut, wir haben insgesamt 40GB Speicher zur Verfügung, wir hatten Max Heap Größe auf 2GB für jede JVM (2 GB ist manchmal notwendig). Da es nie der Fall war, dass zu viele "große" Stapeljobs gleichzeitig ausgeführt wurden, gab es nie Speicherprobleme. Bis wir auf Java 8 vm umgezogen sind. Es scheint, dass der vollständige GC weniger häufig ausgelöst wird. Wir haben JVM in der Speicherbelegung meistens im Leerlauf. Wenn ich einen GC durch den Aufruf von jcmd triggere, kann ich sehen, dass der OldGen von 1 GB auf 200 MB sinkt.
Ich weiß, das ist kein gutes Setup, um 20 JVMs mit maximal 2 GB Heap + Stack + Metaspace zu haben, die viel mehr als die verfügbaren 40 GB Speicher wären. Aber es ist eine Situation, mit der wir leben müssen. Und ich wäre überrascht, wenn es eine Möglichkeit gibt, eine maximale Heap-Größe für einen Cluster von mehreren JVMs festzulegen. Also muss ich mir andere Lösungen ausdenken.
Ich war auf der Suche nach einer VM-Option, die die VM anweist, einen vollständigen GC in regelmäßigen Abständen zu machen, dies würde sehr wahrscheinlich unser Problem lösen. Aber ich kann keine VM Option dafür finden.
Irgendwelche Vorschläge, wie wir dies einrichten können, um Speicherwechsel zu vermeiden?
EDIT: Hier ist ein Ausschnitt aus dem gc-Log:
2016-04-14T01:02:49.413+0200: 37428.762: [Full GC (Ergonomics) [PSYoungGen: 28612K->0K(629248K)] [ParOldGen: 1268473K->243392K(1309184K)] 1297086K->243392K(1938432K), [Metaspace: 120332K->120320K(1181696K)], 0.3438924 secs] [Times: user=1.69 sys=0.02, real=0.35 secs]
2016-04-14T01:02:52.442+0200: 37431.792: [GC (Allocation Failure) [PSYoungGen: 561664K->67304K(629248K)] 805056K->310696K(1938432K), 0.0315138 secs] [Times: user=0.26 sys=0.00, real=0.03 secs]
2016-04-14T01:02:54.809+0200: 37434.159: [GC (Allocation Failure) [PSYoungGen: 628968K->38733K(623104K)] 872360K->309555K(1932288K), 0.0425780 secs] [Times: user=0.35 sys=0.00, real=0.04 secs]
...
2016-04-14T10:09:03.558+0200: 70202.907: [GC (Allocation Failure) [PSYoungGen: 547152K->41386K(531968K)] 1545772K->1041036K(1841152K), 0.0255883 secs] [Times: user=0.18 sys=0.00, real=0.02 secs]
2016-04-14T10:20:53.634+0200: 70912.984: [GC (Allocation Failure) [PSYoungGen: 531882K->40733K(542720K)] 1531532K->1042107K(1851904K), 0.0306816 secs] [Times: user=0.22 sys=0.02, real=0.03 secs]
2016-04-14T10:23:10.830+0200: 71050.180: [GC (System.gc()) [PSYoungGen: 60415K->37236K(520192K)] 1061790K->1040674K(1829376K), 0.0228505 secs] [Times: user=0.17 sys=0.01, real=0.02 secs]
2016-04-14T10:23:10.853+0200: 71050.203: [Full GC (System.gc()) [PSYoungGen: 37236K->0K(520192K)] [ParOldGen: 1003438K->170089K(1309184K)] 1040674K->170089K(1829376K), [Metaspace: 133559K->129636K(1196032K)], 1.4149811 secs] [Times: user=11.10 sys=0.02, real=1.42 secs]
Wenn wir eine vollständige GC jede Stunde hätte, wäre es unser Problem zu lösen, denke ich.
System.gc()? Aber Vorsicht: Es ist nicht garantiert, irgendetwas zu tun, normalerweise nennt man es nicht die Lösung. außerdem: Objekte altern, ich denke, dass sehr alte Objekte für immer im Speicher bleiben ... – Exceptyon
Warum müssen Sie einen vollständigen GC erzwingen, anstatt den G1-Kollektor einen vollständigen GC ausführen zu lassen, wenn er sich entscheidet? Sie haben gesagt, dass es 2 GB Heap verwenden kann und Sie versuchen, einen vollständigen GC auszulösen, wenn es nur 1 GB verwendet. Das scheint seltsam. Vielleicht möchten Sie tatsächlich Ihre JVM optimieren, so dass weniger Objekte in der alten Generation landen - angesichts Ihrer Nutzungsmuster, nehme ich an, dass Ihre großen, langlebigen Chargen die alte Generation bevölkern, wenn Sie es wahrscheinlich lieber nicht tun würden . – sisyphus
@Exceptyon Nein, sie tun es ganz sicher nicht. Nicht erreichbare Objekte werden gesammelt, unabhängig vom Alter. – Kayaman