Skip to content

Commit

Permalink
升级到1.0.0版本,改进profile控制机制,改进文件写出机制
Browse files Browse the repository at this point in the history
  • Loading branch information
丁宇 committed May 25, 2012
1 parent 9b972f7 commit d8af232
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 113 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ TProfiler is a code profiling tool.

author:[email protected]

Note: TProfiler requires Java5™ VM.
Note: TProfiler requires Java6™ VM.

Please refer to Wiki for more information:
https://github.com/taobao/TProfiler/wiki
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.taobao</groupId>
<artifactId>tprofiler</artifactId>
<version>0.9.0</version>
<version>1.0.0</version>
<name>profile</name>
<packaging>jar</packaging>
<dependencies>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/taobao/profile/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Main {
* @param inst
*/
public static void premain(String args, Instrumentation inst) {
Manager.instance().initialization();
inst.addTransformer(new ProfTransformer());
Manager.instance().startupThread();
}
Expand Down
122 changes: 74 additions & 48 deletions src/main/java/com/taobao/profile/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
*/
package com.taobao.profile;

import java.util.concurrent.atomic.AtomicBoolean;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.taobao.profile.config.ProfConfig;
import com.taobao.profile.config.ProfFilter;
Expand Down Expand Up @@ -73,62 +75,58 @@ public class Manager {
private ProfConfig profConfig;

/**
* 当前时间大于开始时间小于结束时间,则可以profile. default:false 不可以profile
* 时间标记.当前时间大于开始时间小于结束时间,则可以profile. default:false 不可以profile
*/
private AtomicBoolean canProfile = new AtomicBoolean(false);
private volatile boolean timeFlag = false;
/**
* 暂停profile,将log写到硬盘. default:false 不暂停 true 暂停
* 开关标记.远程开始或结束的开关. default:true 打开状态
*/
private AtomicBoolean pauseProfile = new AtomicBoolean(false);
private volatile boolean switchFlag = true;
/**
* 远程开始或结束的开关. default:true 开始
* profile标记.是否可以profile. default:false 不可以profile
*/
private AtomicBoolean switchProfile = new AtomicBoolean(true);
private volatile boolean profileFlag = false;

/**
* 开始时间结束时间控制线程
*/
private final TimeControlThread controlThread;
private TimeControlThread controlThread;
/**
* 对外提供Socket开关
*/
private final InnerSocketThread socketThread;
private InnerSocketThread socketThread;
/**
* 将性能分析数据写出到磁盘
*/
private final DataDumpThread dumpThread;

private DataDumpThread dumpThread;
/**
* 采样线程
*/
private final SamplerThread samplerThread;
private SamplerThread samplerThread;
/**
* 启动时间是否大于采集结束时间
*/
private boolean moreThanEndTime;

/**
* 私有构造器
*/
private Manager() {
private Manager() {}

/**
* 初始化配置
*/
public void initialization() {
profConfig = new ProfConfig(DEFAULT_CONFIG);
NEED_NANO_TIME = profConfig.isNeedNanoTime();
IGNORE_GETSET_METHOD = profConfig.isIgnoreGetSetMethod();
METHOD_LOG_PATH = profConfig.getMethodFilePath();
// 判断启动时间是否大于采集结束时间 2012-05-25
DateFormat df = new SimpleDateFormat("HH:mm:ss");
String now = df.format(new Date());
moreThanEndTime = (now.compareTo(profConfig.getEndProfTime()) > 0 ) ? true : false;

setProfFilter(profConfig);

controlThread = new TimeControlThread(profConfig);
controlThread.setName("TProfiler-TimeControl");
controlThread.setDaemon(true);

socketThread = new InnerSocketThread();
socketThread.setName("TProfiler-InnerSocket");
socketThread.setDaemon(true);

dumpThread = new DataDumpThread(profConfig);
dumpThread.setName("TProfiler-DataDump");
dumpThread.setDaemon(false);

samplerThread = new SamplerThread(profConfig);
samplerThread.setName("TProfiler-Sampler");
samplerThread.setDaemon(false);
}

/**
Expand All @@ -153,42 +151,46 @@ public static boolean isIgnoreGetSetMethod() {
}

/**
* @param pause
* @param timeFlag the timeFlag to set
*/
public void setPauseProfile(boolean pause) {
this.pauseProfile.getAndSet(pause);
public void setTimeFlag(boolean value) {
timeFlag = value;
}

/**
* @param switchProfile
* the switchProfile to set
* @param switchFlag the switchFlag to set
*/
public void setSwitchProfile(boolean switchProfile) {
this.switchProfile.getAndSet(switchProfile);
public void setSwitchFlag(boolean value) {
switchFlag = value;
}

/**
* @return the switchProfile
* @param profileFlag the profileFlag to set
*/
public boolean getSwitchProfile() {
return switchProfile.get();
public void setProfileFlag(boolean value) {
profileFlag = value;
}

/**
* @param canProfile
* the canProfile to set
* 判断当前是否可以采集数据
* @return
*/
public void setCanProfile(boolean canProfile) {
this.canProfile.getAndSet(canProfile);
public boolean canProfile() {
return profileFlag;
}

/**
* 判断当前是否可以采集数据
*
* @return
*/
public boolean canProfile() {
return canProfile.get() && switchProfile.get() && !pauseProfile.get();
public boolean getSwitchFlag() {
return switchFlag;
}

/**
* @return the timeFlag
*/
public boolean getTimeFlag() {
return timeFlag;
}

/**
Expand All @@ -197,7 +199,15 @@ public boolean canProfile() {
* @return
*/
public boolean canDump() {
return canProfile.get() && switchProfile.get();
return timeFlag && switchFlag;
}

/**
* 启动时间是否大于profile结束时间
* @return
*/
public boolean isMoreThanEndTime(){
return moreThanEndTime;
}

/**
Expand Down Expand Up @@ -228,6 +238,22 @@ private void setProfFilter(ProfConfig profConfig) {
* @param config
*/
public void startupThread() {
controlThread = new TimeControlThread(profConfig);
controlThread.setName("TProfiler-TimeControl");
controlThread.setDaemon(true);

socketThread = new InnerSocketThread();
socketThread.setName("TProfiler-InnerSocket");
socketThread.setDaemon(true);

dumpThread = new DataDumpThread(profConfig);
dumpThread.setName("TProfiler-DataDump");
dumpThread.setDaemon(false);

samplerThread = new SamplerThread(profConfig);
samplerThread.setName("TProfiler-Sampler");
samplerThread.setDaemon(false);

controlThread.start();
socketThread.start();
dumpThread.start();
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/taobao/profile/Profiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ public static void End(int methodId) {
long[] frameData = thrData.stackFrame.pop();
long id = frameData[0];
if (methodId != id) {
thrData.stackFrame.pop();
return;
}
long useTime = endTime - frameData[2];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ public class ProfilerLogAnalysis {
*/
public static void main(String[] args) {
if (args.length != 4) {
System.err
.println("Usage: <tprofiler.log path> <tmethod.log path> <topmethod.log path> <topobject.log path>");
System.err.println("Usage: <tprofiler.log path> <tmethod.log path> <topmethod.log path> <topobject.log path>");
return;
}
ProfilerLogAnalysis analysis = new ProfilerLogAnalysis(args[0], args[1]);
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/taobao/profile/runtime/MethodCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ public synchronized static void UpdateLineNum(int id, int linenum) {
* @param methodName
*/
public synchronized static void UpdateMethodName(int id, String className, String methodName) {
mCacheMethods.get(id).setMClassName(className);
mCacheMethods.get(id).setMMethodName(methodName);
MethodInfo methodInfo = mCacheMethods.get(id);
methodInfo.setMClassName(className);
methodInfo.setMMethodName(methodName);
}

/**
Expand Down
37 changes: 23 additions & 14 deletions src/main/java/com/taobao/profile/thread/DataDumpThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,33 @@ public DataDumpThread(ProfConfig config) {
* @see java.lang.Thread#run()
*/
public void run() {
while (true) {
try {
TimeUnit.SECONDS.sleep(eachProfUseTime);
if (!Manager.instance().canDump()) {
continue;
}
Manager.instance().setPauseProfile(true);
// 等待暂停生效
TimeUnit.MILLISECONDS.sleep(500);

dumpProfileData();
try {
while (true) {
if (Manager.instance().canDump()) {
Manager.instance().setProfileFlag(true);
TimeUnit.SECONDS.sleep(eachProfUseTime);
Manager.instance().setProfileFlag(false);
// 等待已开始的End方法执行完成
TimeUnit.MILLISECONDS.sleep(500L);

dumpProfileData();
}
TimeUnit.SECONDS.sleep(eachProfIntervalTime);
Manager.instance().setPauseProfile(false);
} catch (Exception e) {
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Manager.instance().setProfileFlag(false);
if (fileWriter != null) {
fileWriter.closeFile();
}
// 等待已开始的End方法执行完成
try {
TimeUnit.MILLISECONDS.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
Profiler.clearData();
}
Profiler.clearData();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ public void run() {
String command = read(child.getInputStream());

if (Manager.START.equals(command)) {
Manager.instance().setSwitchProfile(true);
Manager.instance().setSwitchFlag(true);
} else if (Manager.STATUS.equals(command)) {
write(child.getOutputStream());
} else if (Manager.FLUSHMETHOD.equals(command)) {
MethodCache.flushMethodData();
} else {
Manager.instance().setSwitchProfile(false);
Manager.instance().setSwitchFlag(false);
}
child.close();
}
Expand Down Expand Up @@ -102,7 +102,7 @@ private String read(InputStream in) throws IOException {
*/
private void write(OutputStream os) throws IOException {
BufferedOutputStream out = new BufferedOutputStream(os);
if (Manager.instance().getSwitchProfile()) {
if (Manager.instance().getSwitchFlag()) {
out.write("running".getBytes());
} else {
out.write("stop".getBytes());
Expand Down
45 changes: 19 additions & 26 deletions src/main/java/com/taobao/profile/thread/SamplerThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,28 @@ public SamplerThread(ProfConfig config) {
*/
public void run() {
try {
// delay 30s
TimeUnit.SECONDS.sleep(30);
while (true) {
if (Manager.instance().canDump()) {
try {
Date date = new Date();
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : map.entrySet()) {
Thread thread = entry.getKey();
StringBuilder sb = new StringBuilder();
sb.append("Thread\t");
sb.append(thread.getId());
sb.append("\t");
sb.append(thread.getName());
sb.append("\t");
sb.append(thread.getState());
sb.append("\t");
sb.append(date);
sb.append("\n");
fileWriter.append(sb.toString());
for (StackTraceElement element : entry.getValue()) {
fileWriter.append(element.toString());
fileWriter.append("\n");
}
fileWriter.flushAppend();
Date date = new Date();
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : map.entrySet()) {
Thread thread = entry.getKey();
StringBuilder sb = new StringBuilder();
sb.append("Thread\t");
sb.append(thread.getId());
sb.append("\t");
sb.append(thread.getName());
sb.append("\t");
sb.append(thread.getState());
sb.append("\t");
sb.append(date);
sb.append("\n");
fileWriter.append(sb.toString());
for (StackTraceElement element : entry.getValue()) {
fileWriter.append(element.toString());
fileWriter.append("\n");
}
} catch (Exception e) {
e.printStackTrace();
TimeUnit.SECONDS.sleep(samplerIntervalTime);
fileWriter.flushAppend();
}
}
// sleep
Expand Down
Loading

0 comments on commit d8af232

Please sign in to comment.