Animated image that only exist for a short period of time. Garbage collection?

Hey everyone I’m very new to Java game development and trying to build a simple top-down zelda-style game. It’s coming along nice and I got all the collision checking, movement and attacking working properly. I think my question is pretty simple:

I have an Animation class which holds an array of images.
I have a drawToTheScreen array which holds a list of Animations.
Everytime the “paint” method is called it goes through that list & draws what’s necessary.
Everything is working fine.

Every time I cut a bush it creates a new Animation object with the Bush being cut up images. Once it finishes the animation it removes itself from the list to be drawn to the screen.

Now there are going to be a lot of bushes you can cut up. If every bush is creating a new Animation object won’t there be a lot of no-longer-used memory being taken up? I know Java takes care of memory itself but is there anyway I can explicitly say “Hey java I’m never going to use this Animation object again after it’s taken off of the drawToTheScreen Array?”. Or by taking it off of the array will Java magically know that I no longer want to store that in memory and I’m not going to use it again?

The Garbage Collector will take care of it as long as you delete it completely (which means, setting the object to equal “null”).

Guess it’s more specific saying assign null to every variable field or array “slot” which might happen to have a reference for the object we want to be disposed of later on! ::slight_smile:
Alternatively, rather than assign null to a variable, assign another object reference to it. The effect is the same! ;D

Every object you have in your code is a reference to memory. Its like pointers in C++. Every object in java is a pointer in your code.

For example,


Game game;

You just created a pointer which would point to memory, which contains an object of type Game.


Game game = new Game();

Now, you really created an object, which is stored into memory, by saying ‘new’.

You can do something like this.

Game game1 = game;

This code says to create a new pointer to memory and set the pointer value to the current memory piece that ‘game’ is pointing to. Now, the game object in memory has 2 references.

Now you can do this:

game = null;

Now, ‘game’ doesn’t point to your object that is in the memory. The number of references game object in memory has is 1.

Now, do this:

game1 = null;

Now, game1 is also pointing to null. The number of references game object in memory has is 0. You cannot get your object back once it has 0 references.

When memory object has 0 references, java’s garbage collector will delete this object for you from memory.

As long as you’re setting pointers to null when you don’t need them anymore, you won’t have memory problems…

PS

The only time I get memory leak problems, is when I get a bug in my code which does this:


while(true){
     list.add("HI");
}

Objects are available for collection after they have 0 references, that is correct. However, setting references ‘null’ is by no means the only way of ‘deleting’ your objects, in fact I don’t think I ever set references to null.

An object’s reference is also destroyed when the object goes out of scope:



public static void main(String[]a) {
    Object o1 = new Object(); // allocated o1, has 1 reference
    someMethod();
    // o2 has no references now, and is marked for collection

    return; // again, this is implicit, but after this, o1 is out of scope, and is also marked.
}

private static void someMethod() {
    Object o2 = new Object(); // allocated o2, has 1 reference
    return; // this is usually implicit, but I'm putting it here for clarity
}

(non-static) Fields of a class go out of scope when there are zero references to the parent instance, local variables when the method returns, etc etc. This is one of the more practical reasons for being in the practice of declaring variables as close to the point as you use them as possible, and keeping them as local as possible.

More interesting cases happen with things like HashMaps, where references themselves are stored in a data structure. Take a look at java.lang.ref for special references specifically for manipulating the way the GC interacts with these objects. You probably don’t need (and shouldn’t use) these unless you are making advanced caching data structures however, but it can be helpful to know.

Just make note that none of this ‘deletes’ the object(s). The object is only marked as ready for deletion, the garbage collector has to come around and actually delete the object, and you have little control over when that happens.

EDIT: there are other interesting effects involving object allocation, such as objects being allocated on the stack instead of the heap (or the JIT optimizing away useless code), that is facilitated by something called Escape Analysis, but that is more advanced and I will leave it as a reading exercise if anyone is interested.

[quote=“BurntPizza,post:5,topic:48944”]
1995 called, it wants its GC spec back :slight_smile:

How does a modern GC mark an object that has no more references to it? It can’t, because the GC can’t find it, exactly because there are no references to it anymore.

LIVE objects are traced, marked in the object header (as to avoid endlessly tracing cyclic references), and copied to a new location, where all references to relocated objects are updated. Discarded objects are not deleted, they just linger as meaningless bits in memory, and eventually get overwritten by new objects.

This is the reason modern GCs can allocate hundreds of millions of objects per second, and discard them in less than a 10th of a millisecond, because ‘deletion’ is basically doing nothing at all. A huge amount of live objects AND rewriting all references to the moved objects, that is what takes time to move around heaps.

Of course, I’m sure there is a massively large spec out there somewhere detailing the exact working of the GC, but I don’t think the OP really needs to consider it. I also left out generational collection, etc.

We’re all about abstraction here, don’t worry about implementation, only about how you will interface with it, in this case how to write your code. :point:

Sure, there’s hiding implementation details, but you gave incorrect implementation details. If you don’t think the OP needs to know, then don’t address it… or discuss higher abstraction levels - instead of addressing the details incorrectly. :persecutioncomplex: