Skip to content

Instantly share code, notes, and snippets.

@ztellman
Created May 13, 2014 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ztellman/e819c0238c730f5242d3 to your computer and use it in GitHub Desktop.
Save ztellman/e819c0238c730f5242d3 to your computer and use it in GitHub Desktop.
(ns trice.stack
(:require
[clj-radix :as r])
(:import
[java.lang.reflect
Array]
[java.lang.management
ThreadMXBean
ManagementFactory
ThreadInfo]
[java.lang
StackTraceElement]))
(set! *warn-on-reflection* true)
(defprotocol IThreadSampler
(start [_ period])
(stop [_])
(stack-counts [_]))
;;;
(def ^:private thread-mx-bean
(memoize
(fn []
(ManagementFactory/getThreadMXBean))))
(defn- reversed-stack [^ThreadInfo thread]
(let [runnable? (identical? Thread$State/RUNNABLE (.getThreadState thread))
stack (.getStackTrace thread)
cnt (Array/getLength stack)
ary (object-array cnt)]
(when-not (zero? cnt)
(dotimes [i (dec cnt)]
(aset ary i (aget stack (- cnt i 1))))
(aset ary (dec cnt) [(aget stack 0) (not runnable?)])
ary)))
(defn sample []
(let [^ThreadMXBean bean (thread-mx-bean)
thread-id (.getId (Thread/currentThread))]
(persistent!
(reduce
(fn [r ^ThreadInfo thread]
(let [state (.getThreadState thread)]
(if (or (identical? Thread$State/NEW state)
(identical? Thread$State/TERMINATED state)
(== thread-id (.getThreadId thread)))
r
(if-let [stack (reversed-stack thread)]
(r/update! r stack #(if (nil? %) 1 (inc %)))
r))))
(transient (r/radix-tree))
(.dumpAllThreads bean false false)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment