Skip to content

Commit

Permalink
Potential fix for incorrect CPU usage percentage (see #102)
Browse files Browse the repository at this point in the history
  • Loading branch information
LunNova committed Aug 12, 2018
1 parent 9f31d6f commit 47ba5e7
Showing 1 changed file with 35 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,63 @@
import lombok.val;

import org.minimallycorrect.tickprofiler.util.CollectionsUtil;
import org.minimallycorrect.tickprofiler.util.TableFormatter;

public class UtilisationProfiler extends Profile {
private final Map<String, Long> monitorMap = new HashMap<>();

@Override
public void start() {
val threadMxBean = ManagementFactory.getThreadMXBean();
val elements = parameters.getInt("elements");
if (elements <= 0)
throw new IllegalArgumentException("elements must be > 0");

start(() -> threadMxBean.setThreadCpuTimeEnabled(true), () -> {
val initialTimes = new HashMap<String, Long>();

start(() -> {
threadMxBean.setThreadCpuTimeEnabled(true);

List<Long> threads = Thread.getAllStackTraces().keySet().stream().map(Thread::getId).collect(Collectors.toList());
getThreadCpuTimes(threadMxBean, threads, initialTimes);
}, () -> {
List<Long> threads = Thread.getAllStackTraces().keySet().stream().map(Thread::getId).collect(Collectors.toList());

for (Long threadId_ : threads) {
long threadId = threadId_;
long time = threadMxBean.getThreadCpuTime(threadId);
if (time < 0) {
continue;
}
ThreadInfo thread = threadMxBean.getThreadInfo(threadId, 0);
if (thread != null) {
monitorMap.put(thread.getThreadName(), time);
}
val endTimes = new HashMap<String, Long>();
getThreadCpuTimes(threadMxBean, threads, endTimes);

val endDurations = new HashMap<String, Long>();
for (val e : endTimes.entrySet()) {
endDurations.put(e.getKey(), e.getValue() - initialTimes.getOrDefault(e.getKey(), 0L));
}

targets.forEach(it -> {
val tf = it.getTableFormatter();
dump(tf, elements);
double runTimeNanoSeconds = TimeUnit.SECONDS.toNanos(runTimeSeconds);
tf
.heading("Thread")
.heading("Used CPU Time (%)");
for (String key : CollectionsUtil.sortedKeys(endDurations, elements)) {
tf
.row(key)
.row((100d * endDurations.get(key)) / runTimeNanoSeconds);
}
tf.finishTable();
it.sendTables(tf);
});
}, () -> {
threadMxBean.setThreadCpuTimeEnabled(false);
monitorMap.clear();
});
}

private void dump(final TableFormatter tf, int entries) {
double seconds = TimeUnit.SECONDS.toNanos(runTimeSeconds);
tf
.heading("Thread")
.heading("Used CPU Time (%)");
for (String key : CollectionsUtil.sortedKeys(monitorMap, entries)) {
tf
.row(key)
.row((100d * monitorMap.get(key)) / seconds);
private void getThreadCpuTimes(ThreadMXBean threadMxBean, List<Long> threads, HashMap<String, Long> map) {
for (Long threadId_ : threads) {
long threadId = threadId_;
long time = threadMxBean.getThreadCpuTime(threadId);
if (time < 0) {
continue;
}
ThreadInfo thread = threadMxBean.getThreadInfo(threadId, 0);
if (thread != null) {
map.put(thread.getThreadName(), time);
}
}
tf.finishTable();
}
}

0 comments on commit 47ba5e7

Please sign in to comment.