Note: I had previously posted this on my SourceForge Diary on 6-18-08 , but after two posts to the diary I decided the blog was a better place :).
I have been keeping up work on Spheriosity lately as I have devoted my summer to it. Normally I spent around 7 or 8 hours a day writing code for it. Then on the weekend I try to give myself a bit of a break from staring at the computer screen
Before I get in to the main point of this entry I will just list a few things I have done with Spheriosity recently:
- Added the ability to place a point on a line
- Moved the move point button to the draw section
- Wrote unit tests for the new code (putting a point on a line)
- Added a little information section to the bottom of the window which displays area, radius, etc. so the user has some idea what is going on
There are other small changes and if you really want you can investigate the CVS logs. When I release the next version (hopefully the end of the month) I will introduce a changelog file where I will try to sum up all the new features! As a simple FYI the next feature I plan to work on is parallel transport :) I can’t wait to get this implemented, but I do not think this will be any trivial task so please be patient with me as I work on this.
Anyway the reason I started this journal entry was because I just found a huge memory leak today in Spheriosity. A memory leak!? In Java!? YES! You CAN have memory leaks in Java. This realization hit me pretty hard today when I found out that I was wasting a lot of memory. Before today I had let the lore of Java convince me it was impossible to have memory leaks, but it’s true… you CAN have them.
How is this possible you ask? Well it has to do with how garbage collection works. Yes, in the traditional sense of C/C++ you can not have a memory leak where you personally forget to deallocate a chuck of memory. This still does not explain what I mean by memory leak though. I am talking about what happens when you hold on to a reference of an object long after it is needed. This happens very easily with private class variables and static variables. Lets talk a bit about garbage collection:
(This is simplified and I am sure the Java garbage collector is far from trivial, but I will simply explain what I know) In a nut shell the garbage collector knows it’s time to get rid of an object when there are no more references to it in code. So if you are storing an object in a private class variable and no longer need it you should set that variable to null. Especially if the class is going to be around for most of the life of the program. This is quite plausible with things such as user interfaces. It is also worth mentioning that you can think of this as a tree like structure. If you stop referencing a class at the top of the tree the entire branch will be collected as long as the only references to the sub objects occur within that branch.
In Spheriosity the problem I had was that after a user selected ‘New’ to clear the sphere I simply removed the highest node in the scene graph from the scene graph and did not clear all of the objects out of it. This caused everything in the frontend and backend to be kept around! All it took was a single line to clear out the scene graph. There were issues where I would get rid of some frontend objects but it was still an observer to something in the backend. As such the garbage collector would never collect it.
Now that I have learned all of this I will be extremely careful to avoid any future memory leaks. I am also going to be more careful when I explain memory management in java to people. I hear people say all the time that it is so amazing and they make it sound completely fail proof, but that is NOT the truth. You still need to be careful with how you manage memory. There is an entirely separate issue here known as heap smashing and in short it is caused by calling ‘new’ too much and forcing the garbage collector to work overtime! This is a conversation for another day, however.
I hope that I have enlightened at least one person about some of the pitfalls of Java. I still like the language and the library support is awesome. However I will never again say the memory management is easier than C++. The reality is that you have to be just as careful! Why do I care so much about memory usage? Well, I don’t like programs that are memory hogs so I try to create ones that don’t hog memory in their own right.
Sometimes I start to think Java itself is a memory hog by default because of the virtual machine and I do get concerned about that. However, without Java3D Spheriosity wouldn’t be anything that amazing so for now I will be sticking with Java
PS: The cross platform support is nice too