domingo, 22 de outubro de 2017

How java.io.File.deleteOnExit can cause leaks

If you didn't know this, now you know: calling  java.io.File.deleteOnExit can cause leaks. This is described by  Yan in his java.io.File.deleteOnExit() is evil post.

You may think that you develop applications that won't create too much files and does not runs for many hours, but in an application server running for days this may be a real problem.

In this post I just wanted to share how it can quickly grow your heap memory when dealing a lot of files. See the code below:

Notice that the code deletes the reference to the created file object (nullify it) so it can be collected by the garbage collector. At some point the program will explodes with OutOfMemory error probably due the high amount of String created (when running with small heap).


If you increase the heap and use some tool to get a heap dump of your running application you will see memory content on the *static* Linked used in DeleteOnExitHook class. We can do this in runtime by using jvisualvm (a tool that comes with JDK 1.8). This is the first screenshot I took:



After a few hours the memory occupied by LikedHashMap is 30% of all the memory used by the JVM



This memory will only be released after a JVM restart!

If you are scared about the chars[] and String size growing as well, don't worry, this got improved in JDK 9, however, the issue we are discussing here may still happen with Java 9! See below, after @lasombra_br suggestion I was able to get a Java 9 heap dump using jconsole and as you can see the memory use for Strings are now smaller due the use of byte[] instead using char[] and the LikedHashMap (caused by the deleteOnExit call) quickly pass the memory use by Strings:



In another words, avoid calling java.io.File.deleteOnExit method!

Nenhum comentário:

Postar um comentário