Use finalize() in my case?

finalizer, garbage-collection, java

Solution

An good alternative to `finalize` is the `PhantomReference`. the best way to use it is:

public class FileReference extends PhantomReference<CachedImage> {
  private final File _file;

  public FileReference(CachedImage img, ReferenceQueue<CachedImage> q, File f) {
    super(img, q);
    _file = f;
  }

  public File getFile() {
    _file;
  }
}

Then use it like:

public class CachedImage {

    private static final ReferenceQueue<CachedImage> 
            refQue = new ReferenceQueue<CachedImage>();

    static {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    while (true) {
                        FileReference ref = (FileReference)refQue.remove();
                        File f = ref.getFile();
                        f.delete();
                    }
                } catch (Throwable t) {
                    _log.error(t);
                }
            }
        };
        t.setDaemon(true);
        t.start();
    }

    private final FileReference _ref;

    public CachedImage(BufferedImage bi, File tempFile) {
        tempFile.deleteOnExit();
        saveAndFree(bi, tempFile);
        _ref = new FileReference<CachedImage>(this, refQue, tempFile);
    }
    ...
}

Problem

I have an `ImageWrapper` class that saves images to temporary files in disk in order to free heap memory, and allows reloading them when needed. ``` class ImageWrapper { File tempFile; public ImageWrapper(BufferedImage img) { // save image to tempFile and gc() } public BufferedImage getImage() { // read the image from tempFile and return it. } public void delete() { // delete image from disk. } } ``` My concern is, how to make sure that files gets deleted when such `ImageWrapper`'s instance is garbage collected (otherwise I risk filling the disk with unneeded images). This must be done while the application is still running (as opposed to during-termination cleanup suggestions) due to the fact that it is likely to run for long periods. I'm not fully familiar with java's GC concept, and I was wondering if `finalize()` is what I'm looking for. My idea was to call delete() (on a separate Thread, for that matters) from an overriden `finalize()` method. Is that the right way to do it? UPDATE: I don't think I can `close()` the object as suggested by many users, due to the fact that each such image is fetched to a list of listeners which I don't control, and might save a reference to the object. the only time when I'm certain to be able to delete the file is when no references are held, hence I thought `finalize()` is the right way. Any suggestions? UPDATE 2: What are the scenarios where `finalize()` will not be called? If the only possibles are exiting the program (in an expected/unexpected way), I can take it, because it means I risk only one unneeded temp file left un deleted (the one that was processed during exiting).

Original source

Related problems