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;
}
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;
}
- duplicates
-
JDK-4872014 File.cancelDeleteOnExit() to avoid JVM crashes
- Open
-
JDK-8193072 File.delete() should remove its path from DeleteOnExitHook.files
- Open