!7 cmodule2 > DynPrintLogAndEnabled { switchable double interval = 1.0; // seconds sclass Entry { long threadID; S threadName; WeakRef thread; StackTraceElement[] stackTrace; bool runnable; } transient L entries; transient volatile Map stackTraces; // weakHashMap transient volatile Map runnableStackTraces; start { dm_reloadOnFieldChange enabled(); if (enabled) dm_doEvery(interval, r { if (!enabled) ret; var raw = allThreadsWithStackTraces(); setField(entries := map(raw, (t, st) -> { new Entry e; e.threadID = threadID(t); e.threadName = threadName(t); e.thread = weakRef(t); e.stackTrace = st; e.runnable = isThreadRunnable_x(t, st); })); setField(stackTraces := toWeakHashMap(raw)); setField(runnableStackTraces := mapToWeakHashMap(filter(entries, e -> e.runnable), e -> pair(e.thread!, e.stackTrace))); vmBus_send freshStackTraces(stackTraces, weakRef(me())); }); } S renderStats() { ret stackTraces == null ? "" : n2(stackTraces, "thread") + " / " + n2(runnableStackTraces) + " runnable"; } visual dm_calculatedCenteredLabel renderStats(); }