2013-10-24 19 views
8

Ich habe GC-Protokoll aktiviert mit -XX:+PrintTenuringDistribution. Aber ich bin ziemlich verwirrt mit der tenuring Verteilung unten.So lesen Sie die Ausgabe von + PrintTenuringDistribution

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.

2013-10-19T19:46:30.244+0800: 169797.045: [GC2013-10-19T19:46:30.244+0800: 169797.045: [ParNew 
Desired survivor size 87359488 bytes, new threshold 4 (max 4) 
- age 1: 10532656 bytes, 10532656 total 
- age 2: 14082976 bytes, 24615632 total 
- age 3: 15155296 bytes, 39770928 total 
- age 4: 13938272 bytes, 53709200 total 
: 758515K->76697K(853376K), 0.0748620 secs] 4693076K->4021899K(6120832K), 0.0756370 secs] [Times: user=0.42 sys=0.00, real=0.07 secs] 
2013-10-19T19:47:10.909+0800: 169837.710: [GC2013-10-19T19:47:10.909+0800: 169837.711: [ParNew 
Desired survivor size 87359488 bytes, new threshold 4 (max 4) 
- age 1: 9167144 bytes, 9167144 total 
- age 2: 9178824 bytes, 18345968 total 
- age 3: 16101552 bytes, 34447520 total 
- age 4: 21369776 bytes, 55817296 total 
: 759449K->63442K(853376K), 0.0776450 secs] 4704651K->4020310K(6120832K), 0.0783500 secs] [Times: user=0.43 sys=0.00, real=0.07 secs] 

EDIT:

Dies wurde als ein Fehler in Jvm selbst bestätigt aufgrund einer Race-Bedingung, das Objekt in behaupten.

Die ausführliche Diskussion ist hier zu finden:

http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2013-October/001635.html

+0

Was sieht fischig aus, ich schlage vor, Sie auf der Mailingliste OpenJDK zu fragen [email protected] –

+0

Danke Alexey. Ich habe die Antwort von der Mailingliste erhalten. Dies ist eigentlich ein Bug in jvm. –

Antwort

2

Sie das Protokoll richtig zu lesen, liegt das Problem auf der tenuring Schwelle, die Sie auf 4. angegeben haben

The GC parameter “-XX:MaxTenuringThreshold” defines how many minor GC cycles 
an object can stay in the survivor spaces until it finally gets tenured to the 
old space. 

So haben Sie Bytes von einer Aufräumaktion 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.

-XX:MaxTenuringThreshold=0—Makes the full NewSize available to every NewGC cycle, 
and reduces the pause time by not evaluating tenured objects. Technically, 
this setting promotes all live objects to the older generation, rather 
than copying them 
+0

Danke, aber das beantwortet meine Frage nicht. Meine Frage ist, ob die Invariante "alle Bytes in Alter n aus Alter n-1 in der vorherigen GC" wahr ist. Das Protokoll sagt, es ist nicht, aber es ist schwer zu erklären. –

+0

Es tut mir leid, nicht klar genug auf die Antwort zu sein, Bytes bewegen sich von Alter zu Alter erst, nachdem der Schwellenwert erreicht wurde. So können Sie 1MB in einem bestimmten Alter für 4 gc Runden sitzen haben, bevor Sie in das 'n + 1'-Alter wechseln. –

+1

Danke Guillermo. Diese Alterungstabelle ist nur für ParNew GC (in der jungen Generation). Sobald ein Objekt von einer Runde ParNew GC überlebt (kopiert nach Überlebender, nicht altes Gen), wird seine Alterungszahl um eins erhöht. Es sollte also immer ins Alter n + 1 verschoben werden. Jetzt ist es bestätigt, dass dies ein Bug von jvm selbst ist. Danke trotzdem. –

3

Diskussion auf OpenJDK-Mailingliste ([email protected]) schlägt vor, was solche anormalen tenuring Verteilung Bericht ein Ergebnis der Racebedingung zwischen Threads ist je Alterszähler undating.

Fehler JDK-8027363 wurde ausgefüllt.

Auszug aus bug:

Hier ist das Problem: Im Code zum Kopieren eines Zielobjekts in der Überlebende Raum oder in alten gen können mehrere Threads ein Objekt Anspruch Rennen. 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.