Skip to content

Commit 5b690ab

Browse files
Restore :debug functionality
1 parent 048527d commit 5b690ab

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ Once loaded, you can measure objects like this:
5656
(mm/measure (object-array (repeatedly 100 #(String. "hello"))) :bytes true)
5757
;=> 2848
5858

59+
-;; :debug true can be passed to print the object hierarchy. You can also pass an
60+
-;; integer number to limit the number of nested levels printed.
61+
-
62+
-(mm/measure (apply list (range 4)) :debug true)
63+
-
64+
-; root [clojure.lang.PersistentList] 256 bytes (40 bytes)
65+
-; |
66+
-; +--_first [java.lang.Long] 24 bytes (24 bytes)
67+
-; |
68+
-; +--_rest [clojure.lang.PersistentList] 192 bytes (40 bytes)
69+
-; |
70+
-; +--_first [java.lang.Long] 24 bytes (24 bytes)
71+
-; |
72+
-; +--_rest [clojure.lang.PersistentList] 128 bytes (40 bytes)
73+
-; |
74+
-; +--_first [java.lang.Long] 24 bytes (24 bytes)
75+
-; |
76+
-; +--_rest [clojure.lang.PersistentList] 64 bytes (40 bytes)
77+
-; |
78+
-; +--_first [java.lang.Long] 24 bytes (24 bytes)
79+
5980
;; Custom MemoryMeter object can be passed. See what you can configure here:
6081
;; https://github.com/jbellis/jamm/blob/master/src/org/github/jamm/MemoryMeter.java
6182
```

src/clj_memory_meter/core.clj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,6 @@
128128
builder (.getDeclaredMethod mm-class "builder" (into-array Class []))]
129129
(.invoke builder nil (object-array 0))))
130130

131-
(def ^:private memory-meter
132-
(delay (.build (meter-builder))))
133-
134131
(defn- convert-to-human-readable
135132
"Taken from http://programming.guide/java/formatting-byte-size-to-human-readable-format.html."
136133
[bytes]
@@ -147,12 +144,21 @@
147144
(defn measure
148145
"Measure the memory usage of the `object`. Return a human-readable string.
149146
147+
:debug - if true, print the object layout tree to stdout. Can also be set to
148+
a number to limit the nesting level being printed.
150149
:shallow - if true, count only the object header and its fields, don't follow
151150
object references
152151
:bytes - if true, return a number of bytes instead of a string
153152
:meter - custom org.github.jamm.MemoryMeter object"
154153
[object & {:keys [debug shallow bytes meter]}]
155-
(let [m (or meter @memory-meter)
154+
(let [m (or meter
155+
(let [builder (meter-builder)]
156+
(cond (and debug (boolean? debug))
157+
(.printVisitedTree builder)
158+
159+
(integer? debug)
160+
(.printVisitedTreeUpTo builder debug))
161+
(.build builder)))
156162
byte-count (if shallow
157163
(.measure m object)
158164
(.measureDeep m object))]

test/clj_memory_meter/core_test.clj

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns clj-memory-meter.core-test
22
(:require [clj-memory-meter.core :as sut]
3+
[clojure.string :as str]
34
[clojure.test :refer :all])
45
(:import org.spdx.library.model.license.LicenseInfoFactory))
56

@@ -10,10 +11,39 @@
1011
(is (= 80 (sut/measure (java.io.File. "/") :bytes true)))
1112
(is (= 24 (sut/measure (java.time.Instant/now) :bytes true))))
1213

14+
(defmacro capture-system-out [& body]
15+
`(let [baos# (java.io.ByteArrayOutputStream.)
16+
sw# (java.io.PrintStream. baos#)
17+
bk-out# (System/out)]
18+
(System/setOut sw#)
19+
~@body
20+
(.flush (System/out))
21+
(System/setOut bk-out#)
22+
(String. (.toByteArray baos#))))
23+
1324
(deftest output-test
1425
(is (= "240 B" (sut/measure [])))
1526
(is (= "3.1 KiB" (sut/measure (vec (range 100)))))
16-
(is (= "2.8 MiB" (sut/measure (vec (range 100000))))))
27+
(is (= "2.8 MiB" (sut/measure (vec (range 100000)))))
28+
29+
(testing ":debug true"
30+
(is (str/ends-with? (str/trim (capture-system-out (sut/measure (apply list (range 4)) :debug true)))
31+
(str/trim "
32+
root [clojure.lang.PersistentList] 256 bytes (40 bytes)
33+
|
34+
+--_first [java.lang.Long] 24 bytes (24 bytes)
35+
|
36+
+--_rest [clojure.lang.PersistentList] 192 bytes (40 bytes)
37+
|
38+
+--_first [java.lang.Long] 24 bytes (24 bytes)
39+
|
40+
+--_rest [clojure.lang.PersistentList] 128 bytes (40 bytes)
41+
|
42+
+--_first [java.lang.Long] 24 bytes (24 bytes)
43+
|
44+
+--_rest [clojure.lang.PersistentList] 64 bytes (40 bytes)
45+
|
46+
+--_first [java.lang.Long] 24 bytes (24 bytes)")))))
1747

1848
(deftest error-test
1949
;; Only test this against JDK14+.

0 commit comments

Comments
 (0)