JDK-6664633 : DeleteOnExitHook leaks memory (with fix)
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-02-19
  • Updated: 2019-07-08
  • Resolved: 2008-02-19
Related Reports
Duplicate :  
Duplicate :  
Description
A DESCRIPTION OF THE REQUEST :
DeleteOnExitHook registers files which should be deleted at JVM shutdown. Unfortunately, manually deleting such a file does not free the used memory, leading to a memory leak.

JUSTIFICATION :
Some JDBC drivers use temporary files, which they register with File#deleteOnExit() "in case things go wrong", and manually delete after use. Under heavy load, those files are created at the rate of ~200 / second in our production application. The memory used to keep (useless) references to those files are leading to a OutOfMemoryError. Modifying those JDBC drivers is usually *not* an option.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When registering a file for shutdown-time deletion, manually deleting such a file should remove its reference in DeleteOnExitHook.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.IOException;

public class DeleteOnExitHookMemoryLeak {

public static void main(String[] args) throws IOException {
	// this should run forever
	while (true) {
		File file = File.createTempFile("", ".tmp");
		file.deleteOnExit();
		// in theory do some work involving "file" here
		file.delete();
	}
}

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
  Fix for this wrong behaviour:

* add the following method to DeleteOnExitHookMemory:

static void remove(String file) {
	synchronized(files) {
		if(files == null)
			return; // Shutdown in progress

		files.remove(file);
	}
    }


* modify File#delete() to call this new method:

    public boolean delete() {
	SecurityManager security = System.getSecurityManager();
	if (security != null) {
	    security.checkDelete(path);
	}
	boolean deleted = fs.delete(this);
	if (deleted) {
		DeleteOnExitHook.remove(path);
	}
	return deleted;
    }

Comments
EVALUATION The suggested fix is not valid and breaks the file.deleteOnExit spec. Take for example, File f and following code : f.deleteOnExit(); f.delete(); f.createNew() With the submitter's fix the file will not be deleted as expected.
23-06-2011

EVALUATION This issue is also tracked as 4872014.
19-02-2008