question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

spring boot redeploy in tomcat causing a permgen memory leak

See original GitHub issue

I am currently trying to resolve an issue we’re seeing with redeploying a spring boot application that looks to be a problem in the spring boot end not ours?

Links:

Config: Java 11 OS: Windows & Centos Spring boot: 2.5 Tomcat: 9.0.27


The problem/bug:

When deploying on tomcat 9 using java 11 reloading an application results in a PermGen memory leak with the classloader for the application not being GCd. After adding additional configuration only weak and soft references are found in the heap.

Summary of findings:

Reloading a spring boot application deployed as a war in tomcat 9 results in a PermGen memory leak (reported by the find leaks check and checked in VisualVM). In our actual application there is a strong reference to a log4j JMX bean which is removed when running tomcat with -Dlog4j2.disable.jmx=true though even then the org.apache.catalina.loader.ParallelWebappClassLoader for the application is marked as DESTROYED but is not garbage collected.

I attempted to recreate the issue on a simple spring boot starter (see repo linked). Here I found strong references to logging shutdown hooks which are removed when adding logging.register-shutdown-hook=false to the application.properties. Though after adding this property like above the classloader still isn’t being garbage collected.

Cheers

Sam

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
wilkinsonacommented, Dec 7, 2021

As far as I can tell, this problem is specific to Java 11.

Running with Java 8, when an application is undeployed and GC is forced, all of its classes are unloaded and its ClassLoader is garbage collection. Running with Java 11, the ClassLoader is never garbage collected. In both cases, there are no strong references to the ClassLoader. In Java 8, classes loaded by the class loader are only referenced weakly. In Java 11, some of the classes loaded by the class loader are referenced softly. The presence of soft references is key to the difference in behaviour.

Generally speaking, weak references will be cleaned up whenever garbage collection is forced. By contrast, soft references will only be cleaned up when the JVM is under memory pressure. Examining in YourKit the heap of a basic Spring Boot web application running on Java 11 reveals soft references from com.sun.beans.introspect.ClassInfo to various Spring and application classes. These ClassInfo instances are being created by java.beans.Introspector via org.springframework.beans.CachedIntrospectionResults.

CachedIntrospectionResults used to call java.beans.Introspector.flushFromCaches(Class<?>) immediately after introspecting a class. This was removed as, due to changes in the JDK, it was no longer needed. It looks to me like it may be needed again following these changes in the JDK which introduced ClassInfo and a soft reference cache.

0reactions
wilkinsonacommented, Jan 7, 2022

The fix has already been made in the JDK but only in Java 16 and later. For that fix to be effective Framework’s call to flushFromCaches needs to be reinstated as far as I can tell. For Java 11, I’m not sure what can be done. At best, a change here would need to be a reflective hack as just calling flushFromCaches won’t help. The ideal would be a backport of JDK-8231454 to Java 11.

Read more comments on GitHub >

github_iconTop Results From Across the Web

spring-boot tomcat redeploy permgen leak due to logging
Tomcat findleaks reports a leak and visual VM indicates that the classes aren't unloaded. Next steps: Take a heapdump; Load dump in Eclipse ......
Read more >
Tomcat, Spring and memory leaks when undeploying or ...
In this post I'll talk about a new kind of memory leak in Spring applications involving transaction management and initializing beans.
Read more >
Tomcat – java.lang.OutOfMemoryError: PermGen space ...
This causes a memory leak in PermGen Space and eventually causes java.lang.OutOfMemoryError: PermGen space. Another important point is that when you deploy ...
Read more >
Classloader-Releated Memory Issues - Dynatrace
Throughout this ebook chapter, we will cover some of the most common classloader-related memory issues, and how to identify, and solve them. Learn...
Read more >
Java – Spring Boot Metaspace Memory Leak – iTecNote
The application is running using Jetty instead of Tomcat. I have a Reactor event loop running and a couple of scheduled processes. However...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found