分析gclog的程序

由于对Java程序作性能测试,往往要分析gclog。
一般使用的工具为gcviewer。

但是想把gcviewer显示的结果截图到文档中又显得很不好看。
所以利用gcviewer里读取gclog的部分代码作了个,将gclog信息输出到csv文件的工具。

以便用Excel将csv打开,用Excel做出自己想要的gclog分析的图来。

关键代码


BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File( gclog文件路径)));
final DataReader reader = factory.getDataReader(in);
final GCModel model = reader.read();

for (Iterator i = model.getGCEvents(); i.hasNext();) {
GCEvent event = (GCEvent) i.next();

StringBuffer sb = new StringBuffer();
event.toStringBuffer(sb);
System.out.println(sb.toString());
}



完整代码

需要gcviewer-x.xx.jar 如:gcviewer-1.29.jar
GCLogToCSV.java


package cn.pl.gclog2csv;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import com.tagtraum.perf.gcviewer.DataReader;
import com.tagtraum.perf.gcviewer.DataReaderFactory;
import com.tagtraum.perf.gcviewer.GCEvent;
import com.tagtraum.perf.gcviewer.GCModel;

public class GCLogToCSV {

private Env env;

private static final DataReaderFactory factory = new DataReaderFactory();

public GCLogToCSV(String[] args) {
env = analyseParameter(args);
}

public void excute() {
if (env == null) {
printUsage();
return;
}

// final GCViewer viewer = new GCViewer();
// viewer.setVisible(false);
InputStream in = null;
PrintWriter heapOut = null;
PrintWriter newOut = null;
PrintWriter oldPermOut = null;
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss");
try {
heapOut = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(env.getOutputHeapCSV())))));
newOut = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(env.getOutputNewCSV())))));
oldPermOut = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(env.getOutputOldPermCSV())))));

in = new BufferedInputStream(new FileInputStream(new File(env.getInputGCLogPath())));
final DataReader reader = factory.getDataReader(in);
final GCModel model = reader.read();
in.close();
in = null;
writeHeader(heapOut, newOut, oldPermOut);
GCInfo heapInfo = new GCInfo();
GCInfo newInfo = new GCInfo();
GCInfo oldInfo = new GCInfo();
GCInfo permInfo = new GCInfo();
String type;
long offset = 0;
if (env.getStartTime() != null) {
offset = env.getStartTime().getTime();
}
String timpstamp;
boolean getInfoRet;
for (Iterator i = model.getGCEvents(); i.hasNext();) {
GCEvent event = (GCEvent) i.next();
getInfoRet = false;
type = event.getType().toString();
if (offset == 0) {
timpstamp = String.valueOf(event.getTimestamp());
} else {
timpstamp = sdf.format(new Date(offset + (long)(event.getTimestamp() * 1000)));
}
if (GCEvent.Type.GC.toString().equals(type)) {
getInfoRet = getGCInfo(event, newInfo, GCEvent.Type.DEF_NEW.toString());
if (getInfoRet) {
//timestamp,used_newsize,newsize,pausetime
newOut.printf("%s,%s,%s,%s\n",
timpstamp, newInfo.postUsed, newInfo.total, newInfo.pause);
}

getInfoRet = getGCInfo(event, heapInfo, null);
} else if (GCEvent.Type.FULL_GC.toString().equals(type)) {

getInfoRet = getGCInfo(event, oldInfo, GCEvent.Type.TENURED.toString());
if (getInfoRet && getGCInfo(event, permInfo, GCEvent.Type.PERM.toString())) {

//timestamp,used_oldsize,oldsize,old_pausetime,used_termsize,termsize,term_pausetime
oldPermOut.printf("%s,%s,%s,%s,%s,%s,%s\n", timpstamp,
oldInfo.postUsed, oldInfo.total, oldInfo.pause,
permInfo.postUsed, permInfo.total, permInfo.pause);
}

getInfoRet = getGCInfo(event, heapInfo, null);
}
if (getInfoRet) {
//timestamp,used_heapsize,heapsize,pausetime,gc_type
heapOut.printf("%s,%s,%s,%s,%s\n",
timpstamp, heapInfo.postUsed, heapInfo.total, heapInfo.pause, type);
}

//StringBuffer sb = new StringBuffer();
//event.toStringBuffer(sb);
//System.out.println(sb.toString());
}

System.out.println("execute done.");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (heapOut != null) {
heapOut.close();
}
if (newOut != null) {
newOut.close();
}
if (oldPermOut != null) {
oldPermOut.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

private void writeHeader(PrintWriter heapOut, PrintWriter newOut, PrintWriter oldPermOut) {
heapOut.println("timestamp,used_heapsize,heapsize,pausetime,gc_type");
newOut.println("timestamp,used_newsize,newsize,pausetime");
oldPermOut.println("timestamp,used_oldsize,oldsize,old_pausetime,used_termsize,termsize,term_pausetime");
}

private Env analyseParameter(String[] args) {
Env ret = new Env();
String value;
for (int i = 0; i < args.length; i++) {
if ("-i".equals(args[i])) {
value = getParameterValue(args, ++i);
if (value != null) {
ret.setInputGCLogPath(value);
}
} else if ("-o".equals(args[i])) {
value = getParameterValue(args, ++i);
if (value != null) {
ret.setOutputPath(value);
}
} else if ("-st".equals(args[i])) {
value = getParameterValue(args, ++i);
if (value != null) {
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss");
try {
ret.setStartTime(sdf.parse(value));
} catch (ParseException e) {
System.out
.println("Warning: [-st starttime]'s format error. (expect 'yyyy/MM/dd HH:mm:ss')");
}
}
}
}

if (ret.getInputGCLogPath() == null || ret.getOutputPath() == null) {
ret = null;
}

return ret;
}

private String getParameterValue(String[] args, int i) {
String ret = null;
if (i < args.length) {
ret = args[i];
}
return ret;
}

public static void main(String[] args) {
GCLogToCSV gcLogToCSV = new GCLogToCSV(args);
gcLogToCSV.excute();
}

public void printUsage() {
System.out.println("Usage:");
System.out
.println("\tGCLogToCSV -i gclogpath [-o outputcsvpath] [-st starttime(yyyy/MM/dd HH:mm:ss)]");
}

private boolean getGCInfo(GCEvent event, GCInfo gcinfo, String type) {
boolean ret = false;
if (type == null || "".equals(type)) {
gcinfo.postUsed = event.getPostUsed();
gcinfo.total = event.getTotal();
gcinfo.pause = event.getPause();
return true;
}
for (Iterator i = event.details(); i.hasNext();) {
Object o = i.next();
if (o instanceof GCEvent) {
final GCEvent subEvent = (GCEvent)o;
if (subEvent.getType().toString().equals(type)) {
gcinfo.postUsed = subEvent.getPostUsed();
gcinfo.total = subEvent.getTotal();
gcinfo.pause = subEvent.getPause();
ret = true;
break;
}
}
}
return ret;
}

private class GCInfo {
public int postUsed;
public int total;
public double pause;
}

private class Env {

private Date startTime;

private String inputGCLogPath;

private String outputPath;

private String outputNewCSV;

private String outputOldPermCSV;

private String outputHeapCSV;

public Date getStartTime() {
return startTime;
}

public void setStartTime(Date startTime) {
this.startTime = startTime;
}

public String getInputGCLogPath() {
return inputGCLogPath;
}

public void setInputGCLogPath(String inputGCLogPath) {
this.inputGCLogPath = inputGCLogPath;
if (this.outputPath == null) {
setOutputPath(inputGCLogPath);
}
}

public String getOutputPath() {
return outputPath;
}

public void setOutputPath(String outputPath) {
this.outputPath = outputPath;
this.outputNewCSV = outputPath + "_new.csv";
this.outputOldPermCSV = outputPath + "_old_perm.csv";
this.outputHeapCSV = outputPath + "_heap.csv";
}

public String getOutputNewCSV() {
return outputNewCSV;
}

public String getOutputOldPermCSV() {
return outputOldPermCSV;
}

public String getOutputHeapCSV() {
return outputHeapCSV;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值