Archive for June, 2007

Am I leaking?

Monday, June 25th, 2007

Try the following test. Download the attached code, extract the archive, execute ./runscript.groovy, and monitor the resident memory used by the script. In my tests the process footprint steadily grows until the script exits. This is type of behavior is usually indicative of a memory leak; however, upon inspecting the script it doesn’t look like it should be leaking. What is going on?

LeakImage

A HeapDump taken during the script’s execution shows that one of org.codehaus.groovy.runtime.ReferenceMap’s HashMaps has grown to an enormous size containing thousands of entries, each key being a reference to a groovy.lang.MetaClassImpl instance. It seems that every execution of shell.evaluate creates, among other things, a new MetaClassImpl object which is subsequently stored within the ReferenceMap. The longer the script run the larger ReferenceMap grows.

These seems like a proto-typical memory leak. MetatClass objects define behavior for specific java/groovy class. Ironically most of the classes for which the MetaClass objects exist are no longer in memory thus are pure garbage. Yet, the MetaClass objects remain resident due to their existence in the ReferenceMap. A closer look at the HeapDump shows that ReferenceMap’s HashMap is a WeakHashMap whose keys are soft references. This means that the HashMap entries should eventually be collected. When the entries are collected is determined by the GC policy of the VM. By default the IBM JDK collects soft references every 32 garbage collection cycles. As it turns out 32 cycles can take a very long time. Luckily the default soft reference policy can be overridden by supplying the -Xsoftrefthreshold parameter. Voila! Setting -Xsoftrefthreshold1 eliminates the exponential process growth producing a maximum resident memory size to 39MB.

How Fast is Fast Enough?

Tuesday, June 5th, 2007

I mentioned that I don’t believe that Java has any true scripting languages because none of its languages are useful for System Administration. One of specific flaws that all Java scripting languages share is general sluggishness. This begs the question: How fast is fast enough?

tortoise-hare

To answer the question “How fast is fast enough” the question must be put into some context. In this discussion the context is system administration. Complex language tests like mandelbrot are not suitable when speaking in terms of system administration because by their very nature shell scripts are supposed to start-up, perform a simple task, and shutdown. A more appropriate test is measuring how quickly the language can perform an extremely simple task like adding 1+2. For this type of test my threshold for “fast enough” is visually noticing a lag from the time I hit enter on the keyboard to the time the script returns. For me, this equates to about 60ms. By this measure none of the Java scripting languages are fast enough.

Taking the question from the subjective to the objective it is important to understand just how far Java’s scripting languages are from its contemporaries. So, I benchmarked start-up time for the following languages on my Thinkpad T60p with an Intel T2600 processor: BASH, python, perl, jython, jruby, and groovy. The results are listed below.

Language Start-up Time (ms)
BASH 8
python 27
perl 7
ruby 10
jython 900
jruby 1900
groovy 1200


The number speak for themselves, Java’s scripting languages are at least an order of magnitude slower than its non Java counterpart.