ClassLoader leak due to shutdown hooks

Description

We use SpringLiquibase to execute Liquibase during the startup of our web application. Since updating from 3.1.1 to 3.3.1 our integration test for classloader leaks fails. When I look at a heap dump in VisualVM and use "Show Nearest GC Root" on the WebappClassLoader (WCL) it returns the ApplicationShutdownHooks (ASH) class.

Shutdown hooks cannot be used in web applications due to the following references:
RootClassLoader -> ASH
ASH -> Hook
Hook -> WCL

This leaks the entire WCL and will result in PermGen exceptions (JDK<1.8) or heap problems (JDK>=1.8).

Our workaround is to stay at 3.1.1.

Testing in 3.2.1 and 3.2.0 was not possible due to other bugs.

Environment

Liquibase 3.1.1
Spring Platform 1.1.0

Activity

Show:

Petr Kozelka November 6, 2015 at 2:13 PM

The solution with File.deleteOnExit() is problematic, because (from javadoc): Deletion will be attempted only for normal termination of the virtual machine.
But - typically on a CI server - failures do happen and files are consuming the /tmp volume - typically quite a small memdisk.

So, using tempfiles should be IMHO minimized, and temp files should be removed ASAP.

Nathan Voxland June 23, 2015 at 6:54 PM

Will require more changes than I'd like to make in 3.x. Moving to the 4.0 refactoring

Former user April 21, 2015 at 4:37 PM

I have been running in this problem myself now. I'm not sure what Arlo is doing but we experience the problem in 3.1.1 as well. It is caused by using the includeAll tag which causes the whole jar to be unpacked to the temporary directory. The shutdown hook is there to clean it up. So for me the workaround is to manually unfold the includeAll to a few dozen include tags. Maybe Arlo can use this workaround as well. If not, it sure would be interesting to know what the cause of the bug is.

I searched a bit through the code of the current master and while the code looks a bit different, I think the problem is the same.

I guess the clean way would be to maintain a list of cleanup tasks that should be executed after the update took place. Releasing the database lock could be such a cleanup task as well.

Nathan Voxland March 5, 2015 at 5:27 PM

Reopening to investigate further

ArloK January 9, 2015 at 8:46 AM

Sadly this does not solve my issue.

File.deleteOnExit uses java.io.DeleteOnExitHook which adds a ShutdownHook in a static {} block. So it's exactly the same as before :/

Details

Reporter

Fix versions

Affects versions

Priority

Created December 29, 2014 at 3:37 PM
Updated November 6, 2015 at 2:13 PM