Skip to main content
Commonmark migration
Source Link

##Note:

Note:

##Note:

Note:

Edit after updated question
Source Link
rolfl
  • 98.2k
  • 17
  • 220
  • 419

You should not be manually counting references. Instead, you should be letting the garbage collector do the reference management for you, and then hook in to the garbage collection framework when the reference is cleared in Java.

The right tool for the job is the finalize() method. This often-misused method, is actually purpose-designed for this exact case:

the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.

public class Texture {
    ....
    @Override
    protected void finalize() {
        // clear resources kept in external areas to Java....
        .....
    }
}

##Note:

The Following 'Old' answer is based on the first version of the question that made no reference to non-Java memory....

I believe you have a basic misunderstanding of Java memory management. What you say you are doing, you are not actually doing, and this statement 'This works and is OK' is not what you think is happening.

I believe you have a basic misunderstanding of Java memory management. What you say you are doing, you are not actually doing, and this statement 'This works and is OK' is not what you think is happening.

You should not be manually counting references. Instead, you should be letting the garbage collector do the reference management for you, and then hook in to the garbage collection framework when the reference is cleared in Java.

The right tool for the job is the finalize() method. This often-misused method, is actually purpose-designed for this exact case:

the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.

public class Texture {
    ....
    @Override
    protected void finalize() {
        // clear resources kept in external areas to Java....
        .....
    }
}

##Note:

The Following 'Old' answer is based on the first version of the question that made no reference to non-Java memory....

I believe you have a basic misunderstanding of Java memory management. What you say you are doing, you are not actually doing, and this statement 'This works and is OK' is not what you think is happening.

Source Link
rolfl
  • 98.2k
  • 17
  • 220
  • 419

I believe you have a basic misunderstanding of Java memory management. What you say you are doing, you are not actually doing, and this statement 'This works and is OK' is not what you think is happening.

You cannot possibly tell java to release the memory for an object. What you can do though, is remove all references to an object, and, at some point Java GC will scan through and identify that memory as no longer used, and available for reuse.

In your class, you have the 'pixel data', perhaps an array of private byte[] pixels = ..., and in your dispose() method you call pixels = null, which removes the reference to the byte[] array. When the Garbage collector sweeps the heap, it will identify that the byte[] array is no longer referenced, and it will release that space.

This is what you are seeing, and you think 'it works'. But, that is not the solution you should be using.

What you should be doing, is not referencing the texture when it is no longer needed!

In other words, there's a bigger picture here... there is somewhere in you code where you have done:

Texture mytexture = new Texture(pixeldata);

and then, you have a reference to mytexture that you are not releasing.

If you say mytexture = null, then the garbage collector will release the pixel data as well as the texture object.

Instead of finding all the places in your code that use the texture, and calling retain() and release() they should just set their Texture variable to null, and move on if they no longer need the Texture.

If you are not releasing your pixels after doing that, it means you have some place in your code where you are still holding references to the Texture, perhaps some value in a HashMap, an array, or somewhere else where you are holding a reference. Remove those entries, and you will be fine.

Note: it is possible that your program is part of a very, very, tiny, small proportion of programs that may need finer memory control, and need to keep a Texture cached even though no-one is using it at a particular moment in time. Java has Soft-References that may help, but that is not likely to be your solution, and is more complicated than this post warrants....