:cranky: Despite “evidence” that it works, it is not actually doing anything. Java is not C++. You do not use destructors. You do not treat objects as handles that automatically free the resource it links to. Unreachable objects do not prevent new objects from being allocated. Those objects do not hurt you. After an object is dead (and before a garbage collection cycle starts), the “age” of that object is irrelevant. It does not slow down the garbage collection process, only reachable objects can do that. The fact that it is dead means it’s space is reclaimable, only live objects prevent that. It does not prevent new objects from being allocated because it provides space to allocate from.
Free space includes reclaimable memory. The problem with determining free space is that you do not know if a given block of memory is live or dead until it gets garbage collected. If it is dead, that is technically free space. freeSpace() returns an approximate value. That is probably for the reason I described. Your free space is at least as much as your unallocated reserved heap space. The exact space could be as much as the entire heap if every object on the heap is dead and the lower bound can be as low as zero. A function could tell you a lower bound on the amount of free space you have, but you cannot know the exact value unless you stop the entire program, visit every live object on the heap, and deduct that total size from the total heap space.
Calling gc() and then checking freeSpace() does not create more free space. It stops your entire program at an inconvenient time, stops all program threads until the full garbage collection completes, and then starts the program again.
At best (assuming you are using a single thread; gc() is not ignored; gc() triggers a new, immediate, full, stop the world garbage collection cycle; and freeSpace() reflects the exact space that is only possible to know after that process) you only know exactly how much space is free. The amount of free space available for a single threaded program does not change if you call [icode]rt.freeSpace(); rt.gc(); rt.freeSpace()[/icode] in that order. The amount of space available for allocating objects is the same because Java can find new space to reclaim while doing an object allocation. (Garbage collection can be done inline with object creation. Object creation is never prevented if the VM implementation can eventually find space to use even if it has to move things around.)
So if you want to know exactly how much free space you have and are willing to wait to know, then calling gc() then freeSpace() might tell you that. Otherwise you are only forcing an earlier garbage collection cycle (assuming gc() actually does something). There might be some positive side effects if you don’t care about responsiveness, but there are also negative side effects.
And it is true that you can’t force Java to do a garbage collection. Suggesting it do so in a loop would be like suggesting Oracle give you the trademark rights to Java every day until it did so. The VM can ignore your suggestion.