Java Manual-Reference-Counting I have a Java game development framework. Certain classes, such as Texture, need to be disposed as soon as you don't need them - we cannot depend on the Garbage Collector.

For this, I have decided to enforce reference counting like Objective-C. You call retain() when you want to own something, and release() when not anymore. This increases/decreases a counter. When the counter hits 0, dispose() is called - at which point, Texture will gladly free its resources such as pixel data etc.

NOTE

The reason I can't depend on the Garbage Collector, is because things like the pixel data aren't stored in Java, but rather by OpenGL in some bindings. Similar things happen with audio data. So it is necessary to call OpenGL to free that data manually.



On my first attempt, I made an interface:

public interface Retainable {
    void retain();
    void release();
    void dispose();
}


So a class that wants to be part of this MRC scheme would be like

class Texture implements Retainable {
    int retainCount = 1;    // 1 because I want it to begin retained
    public void retain() {
        retainCount += 1;
    }
    public void release() {
        if (--retainCount == 0) {
            dispose();
        }
    }
    public void dispose() {
        // Free pixel data
    }
}




This works and is OK.

However, every class that wants to do be part of the MRC scheme would need to:


Create an int field
Implement retain()
Implement release()
Implement dispose()


From the four points, the only non-redundant point is the last one. Obviously dispose() will differ from one class to another. But all the other points won't differ from class to class - I am repeating code, and I don't like that.



On an attempt to improve the simplicity of this scheme, I decided to make a manager class to keep track of all Retainable objects. The class will have a map, where the keys are the Retainable objects and the values are their integer counts. The class will have retain(obj) and release(obj), which increase/decrease the count in the map. When the count hits 0 it will call dispose() and then remove the object from the map.

public abstract class Manager {
    private static HashMap&lt;Object, Integer&gt; data = new HashMap&lt;Object, Integer&gt;();
    public static void retain(Retainable object) {
        if (data.containsKey(object)) {
            data.put(object, data.get(object) + 1);
        }else{
            data.put(object, 1);
        }
    }
    public static void release(Retainable object) {
        if (data.containsKey(object)) {
            int count = data.get(object);
            if (count == 1) {
                data.remove(object);
                object.dispose();
            }else{
                data.put(object, count - 1);
            }
        }
    }
}




While I understand that "global" stuff isn't likeable, I decided to sacrifice that for the sake of simplifying this scheme as much as possible.

I really like this approach, because now my classes don't need to implement so much redundant stuff. They only need to implement dispose().



There is one thing that still bugs me

I would like that, when you construct a Retainable object, it will automatically have a retain count of 1 (so you don't need to call retain() every time you make a new object).

Then, this means that a Retainable class needs to call

Manager.retain(this);


In their constructor... for all classes. Ahh, if only there was a way to construct objects already retained without having to add this line in their constructor (I know this is a super small and almost meaningless thing, but heck...).



Do you have any ideas to improve this? And, very hopefully, a solution to the annoyance above?
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.
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....