-
-
Save lightai/bd06f1c81259c3200dfbfde58de9ee69 to your computer and use it in GitHub Desktop.
android线程监测,排查性能问题
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static class ThreadMonitor { | |
private void startThreadMonitor() { | |
final Thread mainThread = Thread.currentThread(); | |
ThreadGroup threadGroup = mainThread.getThreadGroup(); | |
final Thread[] allThread = new Thread[threadGroup.activeCount()]; | |
threadGroup.enumerate(allThread); | |
final Map<Thread, ThreadStateTimeLine> timeLineMap = new HashMap<>(allThread.length); | |
for (Thread thread : allThread) { | |
timeLineMap.put(thread, new ThreadStateTimeLine(thread)); | |
} | |
new Thread(new Runnable() { | |
@Override | |
public void run() { | |
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); | |
long time0 = SystemClock.uptimeMillis(); | |
long time; | |
while ((time = SystemClock.uptimeMillis() - time0) < 3000) { | |
// for (Thread thread : allThread) { | |
Thread thread = mainThread; | |
Thread.State currState = thread.getState(); | |
ThreadStateTimeLine timeLine = timeLineMap.get(thread); | |
ThreadStage threadStage; | |
if (timeLine.stateTimeLine.size() == 0) { | |
threadStage = new ThreadStage(currState); | |
threadStage.startUpMillis = time; | |
timeLine.stateTimeLine.add(threadStage); | |
} else { | |
threadStage = timeLine.stateTimeLine.get( | |
timeLine.stateTimeLine.size() - 1); | |
if (currState == threadStage.state) { | |
threadStage.endMillis = time; | |
threadStage.time = threadStage.endMillis - threadStage.startUpMillis; | |
} else { | |
threadStage.endMillis = time; | |
threadStage.time = threadStage.endMillis - threadStage.startUpMillis; | |
threadStage = new ThreadStage(currState); | |
threadStage.startUpMillis = time; | |
timeLine.stateTimeLine.add(threadStage); | |
} | |
if (currState == Thread.State.BLOCKED || currState == Thread.State.WAITING) { | |
StackTraceElement[] elements = mainThread.getStackTrace(); | |
if (threadStage.stackTraceElements == null) { | |
threadStage.stackTraceElements = elements; | |
} else { | |
if (threadStage.stackTraceElements.length != elements.length) { | |
threadStage = new ThreadStage(currState); | |
threadStage.startUpMillis = time; | |
threadStage.stackTraceElements = elements; | |
timeLine.stateTimeLine.add(threadStage); | |
} | |
} | |
} | |
} | |
// } | |
} | |
Object[] threadStages = null; | |
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { | |
threadStages = timeLineMap.get(mainThread).stateTimeLine | |
.stream() | |
.filter(new Predicate<ThreadStage>() { | |
@Override | |
public boolean test(ThreadStage threadStage) { | |
return threadStage.state == Thread.State.BLOCKED; | |
} | |
}) | |
.toArray(); | |
} | |
String result = JSON.toJSONString(threadStages); | |
File file = new File("/sdcard/result.json"); | |
file.setWritable(true); | |
try { | |
new FileOutputStream(file).write(result.getBytes()); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
Log.e(TAG, "main thread:" | |
+ result); | |
} | |
}).start(); | |
} | |
static class ThreadStateTimeLine { | |
Thread thread; | |
List<ThreadStage> stateTimeLine = new ArrayList<>(1000); | |
public ThreadStateTimeLine(Thread thread) { | |
this.thread = thread; | |
} | |
} | |
static class ThreadStage { | |
public long startUpMillis; | |
public long endMillis; | |
public Thread.State state; | |
public long time; | |
public StackTraceElement[] stackTraceElements; | |
public ThreadStage(Thread.State currState) { | |
this.state = currState; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment