Skip to content

Add support for parsing G1 logs that have decimal values in the log form and -XX:+PrintAdaptiveSizePolicy #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import com.tagtraum.perf.gcviewer.model.AbstractGCEvent;
import com.tagtraum.perf.gcviewer.model.GCEvent;
import com.tagtraum.perf.gcviewer.util.NumberParser;
import com.tagtraum.perf.gcviewer.util.ParsePosition;

/**
Expand Down Expand Up @@ -66,18 +65,18 @@ public AbstractDataReaderSun(InputStream in, GcLogType gcLogType) throws Unsuppo
* @param line line that is parsed
* @return amount of memory in kilobyte
*/
private int getMemoryInKiloByte(int memoryValue, char memUnit, String line) {
private int getMemoryInKiloByte(double memoryValue, char memUnit, String line) {
if ('B' == memUnit) {
return memoryValue / 1024;
return (int) (memoryValue / 1024);
}
else if ('K' == memUnit) {
return memoryValue;
return (int) memoryValue;
}
else if ('M' == memUnit) {
return memoryValue * 1024;
return (int) (memoryValue * 1024);
}
else if ('G' == memUnit) {
return memoryValue * 1024*1024;
return (int) (memoryValue * 1024*1024);
}
else {
if (LOG.isLoggable(Level.WARNING)) {
Expand Down Expand Up @@ -142,7 +141,7 @@ protected void setMemoryExtended(GCEvent event, String line, ParsePosition pos)
// if format is "before"->"after"("total"), the next parentesis is the one of the "total"
endOfNextNumber = separatorPos;
}
event.setPreUsed(getMemoryInKiloByte(NumberParser.parseInt(line, currentPos, endOfNextNumber-currentPos-1),
event.setPreUsed(getMemoryInKiloByte(extractNumber(line.substring(currentPos, endOfNextNumber-1)),
line.charAt(endOfNextNumber-1),
line));

Expand All @@ -158,13 +157,13 @@ protected void setMemoryExtended(GCEvent event, String line, ParsePosition pos)
endOfNextNumber = currentPos;
// goto end of next number

while (Character.isDigit(line.charAt(endOfNextNumber))) {
while (Character.isDigit(line.charAt(endOfNextNumber))|| line.charAt(endOfNextNumber) == '.') {
++endOfNextNumber;
}

++endOfNextNumber;
}
event.setPostUsed(getMemoryInKiloByte(NumberParser.parseInt(line, currentPos, endOfNextNumber-currentPos-1),
event.setPostUsed(getMemoryInKiloByte(extractNumber(line.substring(currentPos, endOfNextNumber - 1)),
line.charAt(endOfNextNumber-1),
line));
currentPos = endOfNextNumber;
Expand All @@ -173,7 +172,7 @@ protected void setMemoryExtended(GCEvent event, String line, ParsePosition pos)
// skip "(" and read heap size
++currentPos;
endOfNextNumber = line.indexOf(")", currentPos);
event.setTotal(getMemoryInKiloByte(NumberParser.parseInt(line, currentPos, endOfNextNumber-currentPos-1),
event.setTotal(getMemoryInKiloByte(extractNumber(line.substring(currentPos, endOfNextNumber-1)),
line.charAt(endOfNextNumber-1),
line));
currentPos = endOfNextNumber;
Expand All @@ -190,13 +189,13 @@ protected void setMemory(GCEvent event, String line, ParsePosition pos) throws P
boolean foundPreUsed = end != -2 && parenthesis > end;
if (foundPreUsed) {
start = line.lastIndexOf(' ', end) + 1;
event.setPreUsed(getMemoryInKiloByte(NumberParser.parseInt(line, start, end-start),
event.setPreUsed(getMemoryInKiloByte(extractNumber(line.substring(start, end)),
line.charAt(end),
line));
start = end + 3;
}
for (end = start; Character.isDigit(line.charAt(end)); ++end);
event.setPostUsed(getMemoryInKiloByte(NumberParser.parseInt(line, start, end-start),
event.setPostUsed(getMemoryInKiloByte(extractNumber(line.substring(start, end)),
line.charAt(end),
line));
if (!foundPreUsed) {
Expand All @@ -205,7 +204,7 @@ protected void setMemory(GCEvent event, String line, ParsePosition pos) throws P

start = end + 2;
end = line.indexOf(')', start) - 1;
event.setTotal(getMemoryInKiloByte(NumberParser.parseInt(line, start, end-start),
event.setTotal(getMemoryInKiloByte(extractNumber(line.substring(start, end)),
line.charAt(end),
line));
if (line.charAt(end + 1) == ')') pos.setIndex(end+2);
Expand All @@ -217,14 +216,14 @@ protected void setMemory(GCEvent event, String line, ParsePosition pos) throws P
detailEvent.setType(type);
start = pos.getIndex();
end = line.indexOf("K", pos.getIndex());
detailEvent.setPreUsed(NumberParser.parseInt(line, start, end-start));
detailEvent.setPreUsed((int) extractNumber(line.substring(start, end)));
start = end + 3;
end = line.indexOf("K", start);
detailEvent.setPostUsed(NumberParser.parseInt(line, start, end-start));
detailEvent.setPostUsed((int) extractNumber(line.substring(start, end)));
if (line.charAt(end+1) == '(') {
start = end+2;
end = line.indexOf('K', start);
detailEvent.setTotal(NumberParser.parseInt(line, start, end-start));
detailEvent.setTotal((int) extractNumber(line.substring(start, end)));
// skip ')'
end++;
}
Expand All @@ -234,6 +233,10 @@ protected void setMemory(GCEvent event, String line, ParsePosition pos) throws P
}
}

private double extractNumber(String substring) {
return Double.valueOf(substring);
}

private boolean isGeneration(final String line, final ParsePosition pos) {
final String trimmedLine = line.substring(pos.getIndex()).trim();
return trimmedLine.startsWith("eden")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class DataReaderSun1_6_0G1 extends AbstractDataReaderSun {
private static final String SURVIVOR_AGE = "- age"; // -XX:+PrintTenuringDistribution
private static final String MARK_STACK_IS_FULL = "Mark stack is full.";
private static final String SETTING_ABORT_IN = "Setting abort in CSMarkOopClosure";
private static final String G1_ERGONOMICS = "G1Ergonomics";
private static final List<String> EXCLUDE_STRINGS = new LinkedList<String>();

static {
Expand All @@ -87,7 +88,9 @@ public class DataReaderSun1_6_0G1 extends AbstractDataReaderSun {
// or "...Full GC<timestamp>..."
// or "...)<timestamp>: (initial-mark)..." (where the timestamp including ":" belongs to a concurrent event and the rest not)
// or "...)<timestamp> (initial-mark)..." (where only the timestamp belongs to a concurrent event)
private static Pattern PATTERN_LINES_MIXED = Pattern.compile("(.*\\)|.*Full GC)([0-9.]+.*)");
private static Pattern PATTERN_LINES_MIXED = Pattern.compile("(.*\\)|.*Full GC)([0-9.]+.*)");

private static Pattern PATTERN_G1_ERGONOMICS = Pattern.compile("(.*)\\W\\d+\\.\\d{3}\\W{2}\\[G1Ergonomics .+\\].*");

private static final int GC_DATESTAMP = 1;
private static final int GC_TIMESTAMP = 2;
Expand Down Expand Up @@ -122,6 +125,7 @@ public GCModel read() throws IOException {
final ParsePosition parsePosition = new ParsePosition(0);
Matcher gcPauseMatcher = PATTERN_GC_PAUSE.matcher("");
Matcher linesMixedMatcher = PATTERN_LINES_MIXED.matcher("");
Matcher ergonomicsMatcher = PATTERN_G1_ERGONOMICS.matcher("");
GCEvent gcEvent = null;
int lineNumber = 0;
String beginningOfLine = null;
Expand All @@ -138,6 +142,16 @@ public GCModel read() throws IOException {
for (String i : EXCLUDE_STRINGS) {
if (line.indexOf(i) == 0) continue OUTERLOOP;
}
// remove G1 ergonomics pieces
ergonomicsMatcher.reset(line);
if (ergonomicsMatcher.matches()) {
String firstMatch = (ergonomicsMatcher.group(1));
if (firstMatch.length() > 0) {
beginningOfLine = firstMatch;
}
continue;
}

// if a new timestamp occurs in the middle of a line, that should be treated as a new line
// -> the rest of the old line appears on the next line
linesMixedMatcher.reset(line);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ public static int parseInt(String s, int offset, int length) throws NumberFormat
limit = -Integer.MAX_VALUE;
}
while (i < length) {
digit = s.charAt(offset + i++)-'0';
char c = s.charAt(offset + i++);
if (c == '.') {
i = length;
continue;
}
digit = c -'0';
if (digit < 0 || digit > 9) {
throw new NumberFormatException(s);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ public void youngPauseDateStamp_u2() throws Exception {

assertEquals("number of errors", 0, handler.getCount());
}

/**
* Test parsing GC logs that have PrintAdaptiveSizePolicy turned on
*/
@Test
public void printAdaptiveSizePolicy() throws Exception {
TestLogHandler handler = new TestLogHandler();
handler.setLevel(Level.WARNING);
IMP_LOGGER.addHandler(handler);
DATA_READER_FACTORY_LOGGER.addHandler(handler);

final InputStream in = getClass().getResourceAsStream("SampleSun1_7_0_12PrintAdaptiveSizePolicy.txt");
final DataReader reader = new DataReaderSun1_6_0G1(in, GcLogType.SUN1_7G1);
GCModel model = reader.read();

assertEquals("gc pause", 0.158757, model.getPause().getMax(), 0.000000001);
GCEvent heap = (GCEvent) model.getEvents().next();
assertEquals("heap", 65*1024*1024, heap.getPreUsed());
// test parsing of decimal values
assertEquals("heap", 64.3*1024*1024, (double)heap.getPostUsed(), 1e2);
assertEquals("heap", 92.0*1024*1024, (double)heap.getTotal(), 1e2);

assertEquals("number of errors", 0, handler.getCount());
}

@Test
public void testDetailedCollectionDatestampMixed1() throws Exception {
Expand Down
Loading