1

I'm using OpenGL in Java and I have to delete external resources (like vbos). The recommended way is to have a Disposable interface. However doing that would require me to have nearly every class dealing with resources implement this interface. And I've tried that but it's often not clear to me which object should be responsible for calling the dispose() method. That's why I programmed something like this:

public abstract class Destroyable {
    private static final ArrayList<Runnable> cleanupTasks = new ArrayList<Runnable>();

    public static void cleanup() {
        synchronized (cleanupTasks) {
            for (Runnable cleanupTask : cleanupTasks) {
                cleanupTask.run();
            }
        }
    }

    protected abstract void destroy();

    @Override
    protected void finalize() throws Throwable {
        try {
            synchronized (cleanupTasks) {
                // Let's do cleanup in the main thread as the garbage collector runs in another thread
                cleanupTasks.add(new Runnable() {
                    public void run() {
                        destroy();
                    }
                });
            }
        } finally {
            super.finalize();
        }
    }
}

As the garbage collector won't run most of the time I'm calling Destroyable.cleanup() together with System.gc() every five seconds.

It's not that bad if some of the resources aren't destroyed at the end (like static ones) because I'm deleting the context at the end (which destroys the other resources as well).

Is this a good idea or is there a better way of doing this?

BDL
  • 21,052
  • 22
  • 49
  • 55
torkleyy
  • 1,137
  • 9
  • 26
  • What's the point of the cleanup queue? Why not call `destroy()` directly from `finalize`? – Marko Topolnik Sep 07 '16 at 06:44
  • I'm using this cleanup queue because I can only destroy the resources from thread I created them in. I think most garbage collectors will use another thread for garbage collection. – torkleyy Sep 07 '16 at 07:02
  • Yes, there is actually a dedicated finalizer thread (just one) which drains the finalization queue. You basically had to reimplement it. – Marko Topolnik Sep 07 '16 at 07:07
  • You mean I should create a seperate thread which is responsible for creating and deleting the resources? Because right now I'm creating my resources in the main thread and in the main loop (which is in the main thread) I'm checking if five seconds passed since last cleanup. Which advantage would I have when creating a seperate thread for that? – torkleyy Sep 07 '16 at 07:33
  • No, that's not what I mean. I have no suggestion for you except a remark that relying on `System.gc()` is indeed a very fragile approach, especially in an application very sensitive to STW pauses. – Marko Topolnik Sep 07 '16 at 07:37

0 Answers0