`
Goro
  • 浏览: 173462 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

分析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;
		}
	}
}

0
0
分享到:
评论

相关推荐

    Go-gclog是一个go日志管理库

    当日志文件达到预设大小时,gclog会自动创建新的日志文件,同时保持文件命名规则的一致性,便于后期检索和分析。 3. **自动删除过期日志**: 日志管理中一个常见的问题是旧日志文件的堆积,占用大量存储空间。gc...

    gclog+gcviewer.zip

    这将使JVM在`gc.log`文件中输出包括垃圾回收细节、时间戳等在内的信息,便于我们后续分析。 然后,我们引入了GCViewer工具,这是一个图形化的GC日志分析工具,由Chris Newland开发。GCViewer可以从GC日志中提取数据...

    ga16.zip-分析GC日志native_stderr.log(可分析WAS6.1版本)

    1. **性能优化**:通过分析GC日志,可以识别出频繁的垃圾收集事件,这可能是导致应用响应时间变慢或系统暂停时间过长的原因。 2. **内存泄漏检测**:如果GC日志显示内存使用持续增加,而无法被正常回收,可能存在...

    c#log日志类和日志分析器(源码)

    本文将深入探讨“c# log日志类和日志分析器”的相关知识点,包括日志的创建、存储、分析以及提供的源码在实际项目中的应用。 首先,让我们了解什么是日志。日志是程序运行过程中产生的事件记录,这些记录包含了...

    gcviewer_1.3.4_执行程序与示例

    [GCViewer](https://github.com/chewiebug/GCViewer) 是一款开源的GC日志分析工具。项目的 GitHub 主页对各个指标提供了完整的描述信息 你需要安装了JDK或者Java. 解压之后, 然后双击点击 start.cmd 当然, 直接在...

    GChisto GC日志分析工具

    `GChisto`是一款专门用于分析GC日志的离线工具,虽然其官网可能已经不可访问,但通过搜索引擎如百度,仍可以找到相关的资源和使用教程。 GChisto的主要功能在于帮助开发者和运维人员解析、可视化和理解GC日志,从而...

    gchisto分析工具

    3. **内存配置调整**:分析GC日志可以帮助确定是否需要调整Java虚拟机的内存参数,如新生代大小、老年代大小等。 4. **垃圾收集器选择**:不同的GC算法有不同的性能特点,gchisto的分析结果可以为选择合适的垃圾...

    java9中gc log参数迁移

    例如,`-Xlog:gc:./gc.log`将GC日志输出到当前目录的`gc.log`文件。 3. **`decorators`** 部分允许你添加装饰器,以增强日志输出的信息,比如时间戳(`time`)、进程ID(`pid`)等。 4. **`output-options`** 允许...

    gcviewer134.zip

    GC的效率直接影响到程序的运行速度和内存使用,而分析GC日志是优化其性能的关键步骤。GCViewer 1.34便是一款专门用于解析和可视化Java GC日志的工具,它能够帮助开发者更直观地理解内存管理的情况,从而找出可能存在...

    Java虚拟机GC日志分析

    通过分析GC日志,可以了解Java虚拟机中的内存使用情况。从上面的输出结果可以看到,Java虚拟机中的堆内存被分为三个部分:Young Generation、Old Generation和Perm Generation。 Young Generation是用于存储短期...

    自己的系统的gc参数学习

    JDK自带的JConsole、VisualVM和JFR(Java Flight Recorder)等工具可以帮助我们实时监控和分析GC行为。JFR尤其强大,能够提供丰富的事件和性能指标,对GC调优非常有帮助。 总结,学习和理解GC参数,尤其是G1垃圾...

    java应用JVM的GC频率观察方法

    此外,可以使用`-Xloggc:gc.log`指定日志输出文件,然后通过工具如GCViewer进行日志分析,以获取更直观的GC行为可视化。 2. 在生产环境下,由于直接修改JVM参数可能影响线上服务,因此通常推荐使用专门的监控工具。...

    GChistoGC日志分析工具

    4. **暂停时间分布**:分析GC暂停时间的分布,帮助定位导致应用暂停时间过长的问题。 5. **GC趋势**:通过图表展示GC行为随时间的变化,便于观察内存使用和GC活动的规律。 对于Old Generation问题,GChisto可以帮助...

    GCViewer.zip

    在使用GCViewer时,首先要确保JVM开启了相应的日志记录,这通常通过设置JVM参数来实现,例如使用`-XX:+PrintGCDetails`和`-Xloggc:gc.log`来开启标准GC日志。然后,将生成的日志文件导入GCViewer,工具会自动解析并...

    tomcat GC 优化配置

    ### Tomcat GC 优化配置详解 #### 一、概述 在服务器端应用中,Java虚拟机(JVM)的性能优化至关重要,特别是对于像...此外,定期分析GC日志可以帮助我们更好地理解系统的运行状态,并据此做出进一步的优化决策。

    java 虚拟机问题分析大全

    - **GC日志分析**:通过设置合理的JVM参数来收集GC日志,并使用工具如GC Log Analyzer、VisualVM等分析GC行为,优化垃圾回收策略。 - **代码优化**:根据性能分析的结果,针对性地优化代码逻辑,减少不必要的对象...

    年轻代gc jvm crash

    为了分析具体的问题,我们需要查看`hs_err_pid32506.log`日志文件。这个文件通常记录了JVM崩溃时的详细信息,包括堆栈跟踪、系统环境变量、JVM参数等,这些信息对于诊断问题至关重要。我们可以通过以下步骤进行分析...

Global site tag (gtag.js) - Google Analytics