Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak on DeleteOnExitHook

I have a Java application running 24/7, it has a connection to a MySQL server and a TimerTask (is running Akka). I'm running into OutOfMemoryError after a week or less of operation and the heap dump reveals a LinkedHashMap with over 4 millions of Strings, they have a GC root of java.io.DeleteOnExitHook using 800 MB of heap.

All the Strings are something like /tmp/jar_cachexxxx.tmp

This problem is consistent in two machines running OpenJDK Runtime Environment (build 1.8.0_101-b13). The JDBC driver is the one provided on maven "mysql-connector-java" version 5.1.38 and I'm using the connection pool BoneCP, version 0.8.0.

Anyone has an idea about this leak?

Update -- 5/12/16

The problem has been solved after we've changed the compiler for the project. We noticed that eclipse jar creator was the only thing that has any relation with jar cache, so after we compiled the project with maven, the memory leak was gone.

like image 671
Max Söderlund Avatar asked Oct 18 '16 22:10

Max Söderlund


People also ask

What are the causes of memory leaks?

Memory leak occurs when programmers create a memory in heap and forget to delete it. The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory.

Which action cause memory leak?

In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.

Can logging cause memory leak?

log() does not cause memory leaks.


2 Answers

This is a long-standing and well known bug that has been reported to Sun/Oracle MANY times over the years. The current bug number is JDK-4872014.

The issue is that each time you use the delete-on-exit API the File gets stored into a HashMap. Since in a long-running server your code rarely intentionally exits, the map can grow without bounds if you are doing this with lots of temporary files.

Essentially, the API is not usable with long-running servers because it's not really intended to be used that way. If you need this functionality you need to implement it yourself and run the cleanup on a schedule, with some way to know which files can be deleted.

like image 96
Jim Garrison Avatar answered Oct 21 '22 13:10

Jim Garrison


It only happens when you use the eclipse exporter "Runnable JAR file" and then choose "Package required libraries into generated JAR".

Then the eclipse JAR-in-JAR classloader will be used, which uses an URLClassloader, which will produce a memory leak according to this question: How long are resources used (file descriptor and memory) for Java temporary files (jar_cache####.tmp)?

like image 3
MonitorLizard Avatar answered Oct 21 '22 13:10

MonitorLizard