06 December, 2011

Crashing the JVM

The Java Virtual Machine is quite impressive, considering it is so stable that large corporations and even banks depend on it to perform a myriad of tasks.  Even Google uses it.  So there you go, a great tool which is stable, clean, fast and loved by many.

As you might also know, it works by having byte code being sort of interpreted and executed, in real time.  Now the problems lies not in this relatively intense part of the system, but at a higher level - the language itself.  You see, Java makes it easy to create, use and handle objects, but how the hell can you create an object without ever reserving memory for it, just like in C++, for instance.  Java does this automatically, and it also destroys and gives back memory (to the OS) automatically.

Don't put this kind of code if your building some
arsenal management console.  Really, don't.

That task belongs to the garbage collector, a separate thread running in the background, and then at some point, stops everything (really, it's called "Stopping the world") and removes any unused objects laying around. Basically what can happen is that if the memory is not being cleaned, you end up putting every single new byte in memory, on the heap.  The memory is obviously limited, so eventually it will crash.  This can be caught by "OutOfMemoryError", as you would usually catch normal exceptions.  It is not always possible though, since when the JVM crashes, the problem is "outside" of the program execution, specifically in the memory manager. Segmentation fault, as it is known, happens when the memory can't be managed.

The following code causes this error, and the reason is that we are creating an array of the same array, which eventually adds up to one huge array of array of array of etc.  This basically crashes the whole JVM and will give you a JVM error, which unlike traditional errors, can't be handled.

So essentially, the moral of the story is that even though it is clean and simpler to leave GC out, please, always ensure that you still keep object creation under control, as you do not really know what happens during execution.  It is also important to keep that in mind when coding mobile apps, those devices have much less memory, and processing power for that matter.  Please also note that this code is common on the internet so it is easy to find it (and more crashing code) also in fora and other blogs...

Object[] o = null;
while (true)
o = new Object[]{ o };