Garbage Collection is a life saver. Sure, you don’t have to mess with malloc() and free() and not worry about accidently deallocating objects that are still being referenced. But is GC a cure-all? Does it save you from all memory issues? Worse yet, can it cause more damage than good? Here are three reasons why GC is overrated:
1. GC is not a guard against bad code
GC will NOT clean up objects that are still being referenced. This means, you can simply create huge array and fill with data retrieved from a DB query (and you have idea what the result set would be). This is bad coding – not foreseeing production load/data. No matter how much tuning you do with GC, you will be staring at the infamous java.lang.OutOfMemory Error soon.
GC will NOT clean up objects that are still being referenced
2. GC overhead: You are paying more than you think
Unless your GC cycles complete in ~50 milliseconds and the time between two GC cycles is several minutes, you are being taxed more than you might think. Note that the GC logic is hidden from the developers. Only JVM knows when to invoke a GC and what to do in a GC cycle. It could spend significant time, for example in compacting your fragmented heap.
GC Pause time is critical in interactive applications, where it can totally kill the user experience. It is so critical that some companies spend lot of money in getting large heap (example: 64GB) hoping to avoid GC cycle altogether (Good luck with that…)
3. It is easy to mis-configure GC
Nobody knows for sure how the gazillion GC tuning parameters will behave at runtime. Check out the following statements from Oracle:
Java HotSpot VM Options:
Options that begin with -X are non-standard (not guaranteed to be supported on all VM implementations) , and are subject to change without notice in subsequent releases of the JDK.
Options that are specified with -XX are not stable and are subject to change without notice
How encouraging is that?
If you configure the wrong GC algorithm, your application will have significant performance impact. In most cases, the ideal algorithm can only be determined through brute trial and error which can be time consuming and costly
In conclusion, while Java GC is indeed a break-through in Application memory management, it is not a cure-all. Every day I am bombarded with the same ‘java.lang.OutOfMemory’ error that I saw in the 90s when Applications had 64MB of max heap, only now with 64GB of max heap.
So, what is the cure-all for efficient application when it comes to memory management?
The following combination can get you close:
Well-tuned GC parameters
Meticulous load testing before releasing application
Top 10 reasons why your Enterprise Java Application is slow
5 not so easy ways to monitor the Heap Usage of your Java Application
The most important JVM memory tuning parameter- and how to ace it.
Free Ebook: 9 Free Java Troubleshooting Tools for Application Support Engineers and Developers