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

DeleteOnExitHook leaks memory (with fix)

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P3
    • Resolution: Duplicate
    • Affects Version/s: 6
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_xp

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

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: