Ich habe GC Log mit -XX:+PrintTenuringDistribution
aktiviert. Aber ich bin ziemlich verwirrt mit der tenuring Verteilung unten.
Von Was ich gelesen habe, gibt es 10532656 Bytes im Alter 1 (überlebte von 1 GC) in der ersten GC. In der zweiten GC, 9178824 Bytes im Alter von 2 (überlebte von 2 GCs). Dies ist in Ordnung, da einige Objekte zwischen dem ersten und zweiten GC starben.
Aber in der zweiten GC, 16101552 Bytes sind im Alter von 3, während nur 14082976 Bytes im Alter von 2 in der ersten GC. Ich weiß nicht, warum diese Zahl zunimmt. Sollten nicht alle Bytes im Alter n vom Alter n-1 im vorherigen GC kommen? Oder habe ich diese Zahlen falsch interpretiert?
Danke.
%Vor%BEARBEITEN:
Dies wurde als Bug in jvm selbst aufgrund einer Race Condition beim Beanspruchen des Objekts bestätigt.
Die ausführliche Diskussion finden Sie hier:
Die Diskussion auf der OpenJDK-Mailingliste ([email protected]) legt nahe, was für ein solcher anormaler Tenuring-Verteilungsbericht ein Ergebnis der Race-Bedingung zwischen Threads ist, die pro Alterszähler undatiert werden.
Bug JDK-8027363 wurde ausgefüllt.
Auszug aus Bug:
Hier ist das Problem: Im Code zum Kopieren eines Zielobjekts in den Überlebenden-Raum oder in altes Gen können mehrere Threads darum rennen, ein Objekt zu beanspruchen. In dem Fall, in dem das Alter des Objekts unter dem Tenuring-Schwellenwert liegt oder wenn die ältere Generation kein CMS ist, kopieren wir zuerst das Objekt und dann das Objekt, indem wir den Weiterleitungszeiger an die Kopie übergeben. Die anderen Kopien werden verworfen und der Gewinner-Thread wird fortgesetzt. Das Problem besteht darin, dass die Alterstabelle von allen Threads erhöht wird, die zum Kopieren rennen. Der Fix ist, dass nur der Gewinner des Rennens die Alterstabelle erhöhen sollte, um mehrere Inkremente zu vermeiden.
Sie lesen das Protokoll richtig, das Problem liegt an der Tenuring-Schwelle, die Sie in 4 angegeben haben.
%Vor%Sie müssen also Bytes von einer Spülung zur nächsten akkumulieren, da Sie abhängig von Ihren konfigurierten Tenuring-Schwellenwerten Speicher für ein bestimmtes Alter für viele GC-Runden haben können.
Wenn Sie beispielsweise das gewünschte Verhalten sehen möchten, setzen Sie den Schwellenwert auf 0
.
Tags und Links java garbage-collection jvm