When I define a function that captures some of its variables in the outer scope, such as below, how does Clojure (on a JVM host) actually store the captured environment?
(let [small-datastructure (calculate-small-thing)
large-datastructure (calculate-large-thing)]
(if *feeling-lucky*
(fn capturing-closure [] (do-other-thing small-datastructure))
(use-data large-datastructure))
In particular, the function capturing-closure
only references the small-datastructure
, but not the large-datastructure
. When I return capturing-closure
from this code, will the large-datastructure
still be referenced by capturing-closure
, or will it be released to garbage collection?
I'm open to both direct answers or suggestions for how to accurately measure this.
how does Clojure (on a JVM host) actually store the captured environment?
Every function becomes a class, every captured thing becomes a member field.
When I return
capturing-closure
from this code, will thelarge-datastructure
still be referenced bycapturing-closure
, or will it be released to garbage collection?
The latter.
suggestions for how to accurately measure this.
You can compile the code and inspect the generated .class
files in whatever way you prefer.
Or you can use https://github.com/clojure-goes-fast/clj-java-decompiler.