1212import java .util .logging .Logger ;
1313import java .util .regex .Matcher ;
1414import java .util .regex .Pattern ;
15+
1516import com .tagtraum .perf .gcviewer .model .AbstractGCEvent ;
1617import com .tagtraum .perf .gcviewer .model .AbstractGCEvent .CollectionType ;
1718import com .tagtraum .perf .gcviewer .model .AbstractGCEvent .Concurrency ;
2627import com .tagtraum .perf .gcviewer .util .ParseInformation ;
2728
2829/**
29- * <p>Parses log output from Sun / Oracle Java 1.4 / 1.5 / 1.6. / 1.7
30+ * <p>Parses log output from Sun / Oracle Java 1.4 / 1.5 / 1.6. / 1.7 / 1.8
3031 * <br>Supports the following gc algorithms:
3132 * <ul>
3233 * <li>-XX:+UseSerialGC</li>
@@ -70,6 +71,8 @@ public class DataReaderSun1_6_0 extends AbstractDataReaderSun {
7071 private static final String APPLICATION_TIME = "Application time:" ;
7172 private static final String BEFORE_GC = "Before GC:" ; // -XX:+PrintFLSStatistics=1
7273 private static final String AFTER_GC = "After GC:" ; // -XX:+PrintFLSStatistics=1
74+ private static final String CMS_LARGE_BLOCK = "CMS: Large " ; // -XX:+PrintFLSStatistics=1
75+ private static final String SIZE = "size[" ; // -XX:+PrintFLSStatistics=1
7376
7477 private static final List <String > EXCLUDE_STRINGS = new LinkedList <String >();
7578
@@ -100,9 +103,9 @@ public class DataReaderSun1_6_0 extends AbstractDataReaderSun {
100103 EXCLUDE_STRINGS .add ("Tree Height:" ); // -XX:+PrintFLSStatistics=1
101104 EXCLUDE_STRINGS .add (BEFORE_GC ); // -XX:+PrintFLSStatistics=1
102105 EXCLUDE_STRINGS .add (AFTER_GC ); // -XX:+PrintFLSStatistics=1
103- EXCLUDE_STRINGS .add ("CMS: Large " ); // -XX:+PrintFLSStatistics=1
106+ EXCLUDE_STRINGS .add (CMS_LARGE_BLOCK ); // -XX:+PrintFLSStatistics=1
104107 EXCLUDE_STRINGS .add (" free" ); // -XX:+PrintFLSStatistics=2
105- EXCLUDE_STRINGS .add ("size[" ); // -XX:+PrintFLSStatistics=2
108+ EXCLUDE_STRINGS .add (SIZE ); // -XX:+PrintFLSStatistics=2
106109 EXCLUDE_STRINGS .add ("demand" ); // -XX:+PrintFLSStatistics=2
107110 }
108111
@@ -207,10 +210,10 @@ public DataReaderSun1_6_0(InputStream in, GcLogType gcLogType) throws Unsupporte
207210 }
208211
209212 public GCModel read () throws IOException {
210- if (LOG .isLoggable (Level .INFO )) LOG .info ("Reading Sun / Oracle 1.4.x / 1.5.x / 1.6.x / 1.7.x format..." );
213+ if (LOG .isLoggable (Level .INFO )) LOG .info ("Reading Sun / Oracle 1.4.x / 1.5.x / 1.6.x / 1.7.x / 1.8.x format..." );
211214
212215 try (BufferedReader in = this .in ) {
213- final GCModel model = new GCModel ();
216+ GCModel model = new GCModel ();
214217 model .setFormat (GCModel .Format .SUN_X_LOG_GC );
215218 Matcher mixedLineMatcher = linesMixedPattern .matcher ("" );
216219 Matcher adaptiveSizePolicyMatcher = adaptiveSizePolicyPattern .matcher ("" );
@@ -224,7 +227,7 @@ public GCModel read() throws IOException {
224227 boolean lastLineWasScavengeBeforeRemark = false ;
225228 boolean lineSkippedForScavengeBeforeRemark = false ;
226229 boolean printTenuringDistributionOn = false ;
227- final ParseInformation parsePosition = new ParseInformation (0 );
230+ ParseInformation parsePosition = new ParseInformation (0 );
228231
229232 while ((line = in .readLine ()) != null ) {
230233 ++lineNumber ;
@@ -243,6 +246,11 @@ else if (line.indexOf(APPLICATION_TIME) > 0) {
243246 // when it occurs including timestamp (since about jdk1.7.0_50) it should still be ignored
244247 continue ;
245248 }
249+ else if (startsWith (line , LOG_INFORMATION_STRINGS , false )) {
250+ LOG .info (line );
251+ continue ;
252+ }
253+
246254 if (line .indexOf (CMS_ABORT_PRECLEAN ) >= 0 ) {
247255 // line contains like " CMS: abort preclean due to time "
248256 // -> remove the text
@@ -285,13 +293,8 @@ else if (line.indexOf(APPLICATION_TIME) > 0) {
285293 if (line .indexOf (PRINT_REFERENCE_GC_INDICATOR ) > 0 ) {
286294 line = filterAwayReferenceGc (line );
287295 }
288- if (line .endsWith (BEFORE_GC )) {
289- beginningOfLine .addFirst (line .substring (0 , line .indexOf (BEFORE_GC )));
290- continue ;
291- }
292- else if (line .endsWith (AFTER_GC )) {
293- String beginning = beginningOfLine .removeFirst ();
294- beginningOfLine .addFirst (beginning + line .substring (0 , line .indexOf (AFTER_GC )));
296+ if (lineHasPrintFlsStatistics (line )) {
297+ handlePrintFlsStatistics (line , beginningOfLine );
295298 continue ;
296299 }
297300
@@ -317,7 +320,7 @@ else if (line.endsWith(AFTER_GC)) {
317320 lastLineWasScavengeBeforeRemark = true ;
318321 continue ;
319322 }
320- final int unloadingClassIndex = line .indexOf (UNLOADING_CLASS );
323+ int unloadingClassIndex = line .indexOf (UNLOADING_CLASS );
321324 if (unloadingClassIndex > 0 ) {
322325 beginningOfLine .addFirst (line .substring (0 , unloadingClassIndex ));
323326 continue ;
@@ -328,19 +331,6 @@ else if (isPrintTenuringDistribution(line)) {
328331 beginningOfLine .addFirst (line );
329332 continue ;
330333 }
331- else if (isMixedLine (line , mixedLineMatcher )) {
332- // if PrintTenuringDistribution is used and a line is mixed,
333- // beginningOfLine may already contain a value, which must be preserved
334- String firstPartOfBeginningOfLine = beginningOfLine .pollFirst ();
335- if (firstPartOfBeginningOfLine == null ) {
336- firstPartOfBeginningOfLine = "" ;
337- }
338- beginningOfLine .addFirst (firstPartOfBeginningOfLine + mixedLineMatcher .group (LINES_MIXED_STARTOFLINE_GROUP ));
339-
340- model .add (parseLine (mixedLineMatcher .group (LINES_MIXED_ENDOFLINE_GROUP ), parsePosition ));
341- parsePosition .setIndex (0 );
342- continue ;
343- }
344334 else if (line .indexOf (ADAPTIVE_PATTERN ) >= 0 ) {
345335 if (line .indexOf ("Times" ) > 0 ) {
346336 // -XX:+PrintAdaptiveSizePolicy -XX:-UseAdaptiveSizePolicy
@@ -394,9 +384,23 @@ else if (line.indexOf(HEAP_SIZING_START) >= 0) {
394384 continue ;
395385 }
396386
387+ if (isMixedLine (line , mixedLineMatcher )) {
388+ // if PrintTenuringDistribution is used and a line is mixed,
389+ // beginningOfLine may already contain a value, which must be preserved
390+ String firstPartOfBeginningOfLine = beginningOfLine .pollFirst ();
391+ if (firstPartOfBeginningOfLine == null ) {
392+ firstPartOfBeginningOfLine = "" ;
393+ }
394+ beginningOfLine .addFirst (firstPartOfBeginningOfLine + mixedLineMatcher .group (LINES_MIXED_STARTOFLINE_GROUP ));
395+
396+ model .add (parseLine (mixedLineMatcher .group (LINES_MIXED_ENDOFLINE_GROUP ), parsePosition ));
397+ parsePosition .setIndex (0 );
398+ continue ;
399+ }
400+
397401 AbstractGCEvent <?> gcEvent = parseLine (line , parsePosition );
398402
399- if (lastLineWasScavengeBeforeRemark && !printTenuringDistributionOn ) {
403+ if (lastLineWasScavengeBeforeRemark && !printTenuringDistributionOn ) {
400404 // according to http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2012-August/001297.html
401405 // the pause time reported for cms-remark includes the scavenge-before-remark time
402406 // so it has to be corrected to show only the time spent in remark event
@@ -424,6 +428,34 @@ else if (line.indexOf(HEAP_SIZING_START) >= 0) {
424428 }
425429 }
426430
431+ private boolean lineHasPrintFlsStatistics (String line ) {
432+ return line .endsWith (BEFORE_GC )
433+ || line .endsWith (AFTER_GC )
434+ || line .indexOf (CMS_LARGE_BLOCK ) > 0
435+ || line .indexOf (SIZE ) > 0 ;
436+ }
437+
438+ private void handlePrintFlsStatistics (String line , Deque <String > beginningOfLine ) {
439+ if (line .endsWith (BEFORE_GC )) {
440+ beginningOfLine .addFirst (line .substring (0 , line .indexOf (BEFORE_GC )));
441+ }
442+ else if (line .endsWith (AFTER_GC )) {
443+ String beginning = beginningOfLine .removeFirst ();
444+ beginningOfLine .addFirst (beginning + line .substring (0 , line .indexOf (AFTER_GC )));
445+ }
446+ else if (line .indexOf (CMS_LARGE_BLOCK ) > 0 ) {
447+ String beginning = beginningOfLine .removeFirst ();
448+ beginningOfLine .addFirst (beginning + line .substring (0 , line .indexOf (CMS_LARGE_BLOCK )));
449+ }
450+ else if (line .indexOf (SIZE ) > 0 ) {
451+ String beginning = beginningOfLine .removeFirst ();
452+ beginningOfLine .addFirst (beginning + line .substring (0 , line .indexOf (SIZE )));
453+ }
454+ else {
455+ LOG .warning ("line should contain some known PrintFLSStatistics output, which it doesn't (" + line + ")" );
456+ }
457+ }
458+
427459 private String filterAwayReferenceGc (String line ) {
428460 int lastIndexOfReference = line .lastIndexOf (PRINT_REFERENCE_GC_INDICATOR );
429461 int endOfLastReference = line .indexOf ("]" , lastIndexOfReference ) + 1 ;
0 commit comments