JDK-4513817 : File.deleteOnExit consumes memory
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2001-10-11
  • Updated: 2017-05-19
  • Resolved: 2006-07-17
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Name: gm110360			Date: 10/11/2001

I'm using the imageio.jar form 1.4beta, but with:
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

Every time I use "ImageIO.write(img, "png", outStream)" a temporary file is
created, and the "deleteOnExit()" function is called on that temporary file.
Every "deleteOnExit()" allocates a "struct dlEntry" in the shared "io_util.c"
native source file. This "struct dlEntry" is about 1K in size, and will never be
freed until the system exits, so every time I do an ImageIO.write() I take up
another 1K of memory! This is in a JSP engine that is creating dynamic images,
so I want it to be able to run a long time, but at 1 image/minute it will
consume 1.5MB per day that the JSP engine is up. This is absurd. It seems that
no package should use "deleteOnExit()" dynamically - it guarantees a memory
leak. In a long-running system like a JSP engine, this is completely unacceptable.

It would be better if the temporary file were deleted when the image data was
garbage collected, or some such, so there was no need to allocate a struct
dlEntry in the native code.
(Review ID: 133570) 

Its possible to solve the ImageIo problem if there is a version of
deleteOnExit that returns a unique identifier. Clients such as ImageIO
who remove the file before exit can then call an API to remove the
file referenced by that unique identifier from the internal list of
files to delete on exit.

long deleteOnExit2() 
public static void removeFromDeleteList(long)

###@###.### 2003-04-02

EVALUATION This bug, as described in the description section and relating the Image IO code that uses deleteOnExit to ensure that temporary files are cleaned up, has been fixed by 6291034. It now avoids deleteOnExit completely and uses its own shutdown hook to remove these files. So I am closing this bug as a duplicate of it. For anyone who is concerned with the general problem of not being able to remove files marked deleteOnExit please refer to RFE 4872014.

EVALUATION For diagnosing deleteOnExit issues you can see the following blog: http://blogs.sun.com/roller/page/chegar#diagnosing_deleteonexit_issues

EVALUATION -- 4809375 re-implements deleteOnExit mechanism so that the list of files to be deleted is stored as a list in the java heap. The implementation records the file name as most once so if deleteOnExit is invoked multiple times on the same File then it will not consume any additional memory. This doesn't address the case of temporary files with unique file names but it should improve the diagnosability of such situations as the list will be visible to a java memory profiler.

EVALUATION See comments. This memory leak is a major reliability issue for developers using Image I/O in their server side applications. ###@###.### 2002-11-11 We should investigate ways to improve the implementation of File.deleteOnExit for long-running systems. -- ###@###.### 2002/11/21 It would be a fairly simple matter to remove a file from the delete on exit list when it gets deleted, but that would be a violation of spec. File.deleteOnExit says "Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates." So just because the file is deleted does not mean that it will not get re-opened later. The File object might even get garbage collected but another of the same name might be created later. We are obligated by the spec to remember the path and delete a file there when the VM terminates. There is no way around the memory leak without relaxing this spec. We may be able to offer something in the new FileSystem API in Tiger that solves this problem in a compatible way. ###@###.### 2002-11-22 ###@###.### 2004-05-13 The current spec is abiguous. There may be several files, over the life of the JVM, which meet the criteria of "denoted by this abstract pathname". In this case, to which one of these files does the method apply? I interpret the specification as refering to "the file", a tangible entity, which exists at the time of the call. If the specification were intended to refer to a file which does not currently exist (and may never exist), it would have been more appropriate to say "a file". If this interpretation is accepted, then the current implementation is faulty, and delete() should remove the entry from the list. This would be a minor binary incompatibility, which would be revealed if an application created more than one file with the specified pathname, and relied on the last such file being deleted. I view this as very unlikely, while the memory leak is a real reliablilty problem. Changing the implementation to improve reliability is a reasonable trade-off.

WORK AROUND Name: gm110360 Date: 10/11/2001 Stop and re-start the application (Tomcat/Jakarta in this case) on a regular basis. ====================================================================== One workaround is to disallow the use of cache files by passing false to the static ImageIO.setUseCache() method. This avoids the deleteOnExit() problems and should have little adverse effect on performance, especially in the case of server-side applications working with relatively small images. ###@###.### 2001-11-16