Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6664633

DeleteOnExitHook leaks memory (with fix)

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 6
    • core-libs
    • x86
    • windows_xp

      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;
          }

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: