package com.tagtraum.perf.gcviewer.imp;
import com.tagtraum.perf.gcviewer.DataReader;
import com.tagtraum.perf.gcviewer.GCEvent;
import com.tagtraum.perf.gcviewer.GCModel;
import com.tagtraum.perf.gcviewer.AbstractGCEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.logging.Logger;
import java.util.logging.Level;
/**
* Parses -verbose:gc output from IBM JDK 1.3.0.
*
* Date: Jan 30, 2002
* Time: 5:15:44 PM
* @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
* @version $Id: $
*/
public class DataReaderIBM1_3_0 implements DataReader {
private static Logger LOG = Logger.getLogger(DataReaderIBM1_3_0.class.getName());
private LineNumberReader in;
public DataReaderIBM1_3_0(InputStream in) {
this.in = new LineNumberReader(new InputStreamReader(in));
}
public GCModel read() throws IOException {
if (LOG.isLoggable(Level.INFO)) LOG.info("Reading IBM 1.3.0 format...");
try {
GCModel model = new GCModel(true);
model.setFormat(GCModel.Format.IBM_VERBOSE_GC);
int state = 0;
String line = null;
AbstractGCEvent lastEvent = new GCEvent();
GCEvent event = null;
while ((line = in.readLine()) != null) {
String trimmedLine = line.trim();
if ((!trimmedLine.equals("")) && (!trimmedLine.startsWith("<GC: ")) && (!(trimmedLine.startsWith("<") && trimmedLine.endsWith(">")))) {
if (LOG.isLoggable(Level.WARNING)) LOG.warning("Malformed line (" + in.getLineNumber() + "): " + line);
state = 0;
}
switch (state) {
case 0:
if (line.indexOf("Allocation Failure.") != -1) {
event = new GCEvent();
event.setType(GCEvent.Type.FULL_GC);
event.setTimestamp(lastEvent.getTimestamp() + parseTimeSinceLastAF(line));
state++;
break;
}
case 1:
if (line.indexOf("managing allocation failure, action=1") != -1) {
event.setPreUsed(parsePreUsed(line));
state++;
break;
}
case 2:
if (line.indexOf("freed") != -1 && line.indexOf("unloaded") == -1) {
event.setPostUsed(parsePostUsed(line));
event.setTotal(parseTotalAfterGC(line));
state++;
break;
}
case 3:
if (line.indexOf("expanded heap by ") != -1) {
event.setTotal(parseTotalAfterHeapExpansion(line));
state++;
break;
}
case 4:
if (line.indexOf("completed in ") != -1) {
event.setPause(parsePause(line));
model.add(event);
lastEvent = event;
event = null;
state = 0;
}
default:
}
}
return model;
} finally {
if (in != null)
try {
in.close();
} catch (IOException ioe) {
}
if (LOG.isLoggable(Level.INFO)) LOG.info("Reading done.");
}
}
private double parseTimeSinceLastAF(String line) {
int start = line.indexOf(',') + 2;
int end = line.indexOf(' ', start);
return Double.parseDouble(line.substring(start, end)) / 1000.0d;
}
private int parsePreUsed(String line) {
int start = line.indexOf('(') + 1;
int end = line.indexOf(')', start);
int mid = line.indexOf('/', start);
long a = (Long.parseLong(line.substring(mid + 1, end)) - Long.parseLong(line.substring(start, mid)));
start = line.indexOf('(', start) + 1;
end = line.indexOf(')', start);
mid = line.indexOf('/', start);
long b = (Long.parseLong(line.substring(mid + 1, end)) - Long.parseLong(line.substring(start, mid)));
return (int)((a+b) / 1024l);
}
private int parsePostUsed(String line) {
int start = line.indexOf('(', line.indexOf("freed")) + 1;
int end = line.indexOf(')', start);
int mid = line.indexOf('/', start);
return (int)((Long.parseLong(line.substring(mid + 1, end)) - Long.parseLong(line.substring(start, mid))) / 1024L);
}
private int parseTotalAfterGC(String line) {
int start = line.indexOf('/') + 1;
int end = line.indexOf(')', start);
return (int)(Long.parseLong(line.substring(start, end)) / 1024L);
}
private int parseTotalAfterHeapExpansion(String line) {
int start = line.indexOf("to ") + 3;
int end = line.indexOf(' ', start);
return (int)(Long.parseLong(line.substring(start, end)) / 1024L);
}
private double parsePause(String line) {
int start = line.indexOf("in ") + 3;
int end = line.indexOf(' ', start);
return Double.parseDouble(line.substring(start, end)) / 1000.0d;
}
}
|