How to free images after they're not needed anymor

Hi,

Let’s say I have a game design like this:
Game is the main class. It contains many objects, like Map, list of Units, Menu etc.
The Menu object contains the stuff needed for the startup menu, not the game itself. It contains some flashy images that take pretty much memory, and they’re stored in a BufferedImage.

OK, so when the Game contains a public field like Menu m;
When the game starts I write m = new Menu();
while ( !m.startGame() )
{
// do stuff
}

When startGame() becomes true, the Menu should be deallocated from the memory, cause it won’t be used anymore, at least not until the player clicks on the “Back to Main menu” button, in which case it will load the images again.
What I’d like to know is how to force Java to unload those images? Let’s say each image takes a couple of megabytes, when the actual game starts this will be too much so the Menu object has to be unloaded.

I was thinking of writing
m = null;

and then the garbage collector will pick it up. Will this work? After that line, if I write System.gc(); will the memory be freed immediately?

Waiting for your reply :wink:

You will indeed need to do m = null if you want it to be cleared out by GC, as it will still be referenced, and therefore not collectable.

Cas :slight_smile:

OK, so let’s say I have the Menu and it contains some components in an array, like Comps cmp[];
Each component has a reference towards the Menu, such as “parent”. When I write m = null; the reference to the menu will be lost, but those components still have the reference to it. It is, however, not accessible anymore, cause the components themselves are not referenced from the outside (they’re private, for example). So, will the garbage collector free the memory in this case too, or will it be “careful” and not free the memory till the end of the game?

It’s just one simple rule: if it can’t be reached by any Thread, it’s garbage, no matter how many references there are to it.

Cas :slight_smile:

The GC is a true GC. Things like circular references between dead objects will not keep them from being candidates for collection. As long as an object is not part of a graph that tracks back to a root reference (global, currently active stack ref, etc) it is a candidate for collection.

This is NOT to say however that it WILL get collected. You used a bad word in your question, the word was “force”.

YOU CAN NEVER FORCE COLLECTION OF AN OBJECT. YOU CAN NEVER BE GAURANTEED THAT ANY PARTICUALR OBJECT WILL GET COLLECTED.

Collection is always at the discretion of the VM. Your only gauarntee is that it will make a “best effort” to collect all available memory before it gives up and throws an “out of memory” exception.

In practice, this is rarely much of an issue. Its only an issue if you are trying to count on things like finalizers or reference queues for time critical program logic. Don’t. You have no gaurantee they will ever run.