Determining exactly how much memory objects are using is often
desirable, especially since one of Clojure's few flaws (which is the
JVM's fault, mostly) is that it can be fairly memory-hungry.

So, I took the techniques described in 
http://www.javaworld.com/javaworld/javatips/jw-javatip130.html,
and wrote a Clojure script that does basically the same thing. I have
uploaded it to the files section, under sizeof.clj

Read that article for how it works.The only thing I do different is
that instead of specifying a class,you pass it a method that returns
the object you want to measure. So, for example:

user> (sizeof/sizeof #(new Object))
8 ;;the size of a java.lang.Object.

user> (sizeof/sizeof #(new Double 1.0001))
16 ;;the size of a java.lang.Double

user> (sizeof/sizeof #(let [num (new Double 1.0001)]
                        (fn [] (* num 10))))
32 ;;the size of a closure closing over a double

There is alternative form of sizeof that takes a second parameter,
which specifies how many times to run & save the results. Larger
numbers are by far more accurate, it defaults to 10,000. But if you
want to check the size of the result from a function that might return
something really huge, I provide this so that you can lower the count
and run tests on megabyte-scale objects without causing an OutOfMemory
exception.

A few caveats:

1. This is only an estimate, not a guarentee. You may occasionally get
a fluke result if the JVM does something weird.

2. You can, and will, get different results on different JVMs,
particularly 64 bit vs 32 bit.

3. The JVM does clever optimizations that save space, but can make
benchmarking difficult. For example, if you want to find how much
space a five-character string takes, you might try the following:

user> (sizeof/sizeof #(str "12345"))
0

Something odd happened! The JVM must have detected a constant and
optimized it in a string table, or something of the sort. But if we
try:

user> (sizeof/sizeof #(str "1" "2" "3" "4" "5"))
48

We get something more believable.

4. If there is anything running in a separate thread in the same JVM,
it can mess things up.

5. If the provided function has side effects, it will provide
inaccurate results.


Anyway, I hope it's useful.



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to