Join the war on Classloader leaks

Mattias Jiderhamn – java.jiderhamn.se
 
Join the war on
Mattias Jiderhamn
Classloader leaks
Mattias Jiderhamn – java.jiderhamn.se
 
java.lang.OutOfMemoryError:
PermGen space
:-(
Metaspace
Mattias Jiderhamn – java.jiderhamn.se
 
Local dev env
Mattias Jiderhamn – java.jiderhamn.se
 
Continuous Deploy
.war
Mattias Jiderhamn – java.jiderhamn.se
Agenda
 
What 
does it mean
?
Why 
does it happen
?
Where 
does it leak
?
How 
to avoid
?
OSS examples
Training!
Mattias Jiderhamn – java.jiderhamn.se
 
What?
Mattias Jiderhamn – java.jiderhamn.se
JVM memory
Stack
Heap
PermGen /
Metaspace
Mattias Jiderhamn – java.jiderhamn.se
JVM memory
 
Per thread
Local variables and
method parameters
Stack
Mattias Jiderhamn – java.jiderhamn.se
JVM memory
Heap
Young generation
Old generation /
tenured space
Eden
space
Survivor
space
 
Object instances
Mattias Jiderhamn – java.jiderhamn.se
JVM memory
 
Permanent Generation
java.lang.Class
 instances
etc
Named before JEE and
class unloading
Renamed 
Metaspace
 in Java 8
Aka 
Method area
PermGen /
Metaspace
Mattias Jiderhamn – java.jiderhamn.se
 
 
java.lang.OutOfMemoryError:
PermGen space / Metaspace
 
= Too many classes are loaded
What?
Mattias Jiderhamn – java.jiderhamn.se
 
Why?
Mattias Jiderhamn – java.jiderhamn.se
Reason for OOME
 
1.
Your application is too large
-XX:MaxPermSize=256M
Java 8: Metaspace auto increase by default
2.
java.lang.Class
 instances could not
be garbage collected after redeploy
java.lang.OutOfMemoryError:
PermGen space / Metaspace
Mattias Jiderhamn – java.jiderhamn.se
Reference types
 
Strong (i.e. normal) reference
Never GC:ed if reachable
Soft reference
GC:ed before 
OutOfMemoryError
Weak reference 
(
WeakHashMap
)
GC:ed when no Strong or Soft refs
Phantom reference
… won’t prevent GC
Mattias Jiderhamn – java.jiderhamn.se
Example
Foo
WeakHashMap
 
Map m = new WeakHashMap();
Foo myFoo = new Foo();
m.put(myFoo, ”bar”);
myFoo = null;
Mattias Jiderhamn – java.jiderhamn.se
GC reachability
GC roots
Mattias Jiderhamn – java.jiderhamn.se
Redeploy
Application Server
ClassLoader
app.war
ClassLoader
app.war’
ClassLoader
app.war’’
Mattias Jiderhamn – java.jiderhamn.se
ClassLoader refs
ClassLoader
Class
Class
Class
Instance
Mattias Jiderhamn – java.jiderhamn.se
How leaks happen
Application Server
ClassLoader
Class
Class
Class
Instance
GC root
Mattias Jiderhamn – java.jiderhamn.se
 
Where?
Mattias Jiderhamn – java.jiderhamn.se
Application Server
 
Application Server bugs
Logging frameworks
Apache Commons Logging
Unless 
LogFactory.release()
Log4j - some configs
Unless 
LogManager.shutdown()
java.util.logging
 custom Level
Bean Validation API (JSR 303)
Unified Expression Language (
javax.el
)
 
?
Mattias Jiderhamn – java.jiderhamn.se
GC roots
 
Class loaded by system ClassLoader
static field in JDK classes (
java.*
 etc)
Live thread
Stack – local vars, method params
java.lang.Thread
 instance
Object held as synchronization monitor
JNI references
JVM specials…
Mattias Jiderhamn – java.jiderhamn.se
System classes
 
java.sql.DriverManager
Bean introspection cache, shutdown hooks,
custom default 
Authenticator
, custom
security 
Provider
, custom MBeans, custom
ThreadGroup
, custom property editor, …
Reference to
 
contextClassLoader
 of first caller
Mattias Jiderhamn – java.jiderhamn.se
DriverManager
Mattias Jiderhamn – java.jiderhamn.se
DriverManager
Application Server
app.war
mysql-jdbc.jar
JRE
DriverManager
ClassLoader
com.mysql.jdbc.Driver
 
1) …
 
… or 2)
 
DriverManager.deregisterDriver(…)
Mattias Jiderhamn – java.jiderhamn.se
Context shutdown
public class MyCleanupListener 
implements
javax.servlet.ServletContextListener
 {
  ...
  /** Called when application is undeployed */
  public void 
contextDestroyed
(
    ServletContextEvent servletContextEvent) {
    
DriverManager.deregisterDriver(…);
  }
}
Mattias Jiderhamn – java.jiderhamn.se
Threads
 
Thread stack
Local variables
Method parameters
MyThread extends Thread
MyRunnable implements Runnable
contextClassLoader +
AccessControlContext
 inherited
Example HTTP 1.1 Keep-Alive-Timer
Mattias Jiderhamn – java.jiderhamn.se
Context shutdown
public class MyCleanupListener 
implements
javax.servlet.ServletContextListener
 {
  ...
  /** Called when application is undeployed */
  public void 
contextDestroyed
(
    ServletContextEvent servletContextEvent) {
    
DriverManager.deregisterDriver(…);
    
// Stop threads here!
  }
}
Mattias Jiderhamn – java.jiderhamn.se
Stopping threads
public class MyThread extends Thread {
  public void run() {
    while(
true
) { // Bad idea!
      // Do something
    }
  }
}
Mattias Jiderhamn – java.jiderhamn.se
Stopping threads
public class MyThread extends Thread {
  private boolean running = true;
  public void run() {
    while(running) { // Until stopped
      // Do something
    }
  }
  public void shutdown() {
    running = false;
  }
}
  private 
volatile
 boolean running = true;
Heinz Kabutz / Java Specialists’ - 
The Law of the Blind Spot
Mattias Jiderhamn – java.jiderhamn.se
Threads
 
Thread stack
Local variables
Method parameters
MyThread extends Thread
MyRunnable implements Runnable
contextClassLoader +
AccessControlContext
 inherited
Example HTTP 1.1 Keep-Alive-Timer
ThreadLocal
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
WeakHashMap<Thread, ?>
ThreadLocal
Thread
Foo
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
ThreadLocal
 JavaDoc:
Each thread holds an implicit
reference to its copy of a thread-
local variable as long as the thread
is alive and the 
ThreadLocal
instance is accessible;
 …”
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
ThreadLocalMap
Entry
Thread
ThreadLocal
Foo
 
put()
 
set()
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
 
Pooled threads:
Threads may outlive ClassLoader
ThreadLocal → ThreadGlobal!
 
(?)
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
ThreadLocalMap
Entry
Thread
ThreadLocal
Foo
Class
ClassLoader
 
static
Class
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
ThreadLocalMap
Entry
Thread
ThreadLocal
Foo
Class
ClassLoader
Stale entry
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
ThreadLocalMap
 JavaDoc:
However, since reference queues
are not used, stale entries are
guaranteed to be removed only
when the table starts running out
of space
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
Custom value (incl references)
static ThreadLocal = leak
otherwise = unpredicted GC
Custom ThreadLocal = no leak
Mattias Jiderhamn – java.jiderhamn.se
ThreadLocal
 
try {
  myThreadLocal.set(foo);
}
finally {
  myThreadLocal.remove();
}
 
Always clear your ThreadLocals!
Mattias Jiderhamn – java.jiderhamn.se
 
Known offenders
 
Apache ActiveMQ
Apache Axis
Apache Batik
Apache Commons Pool / DBCP
Apache CXF
AWT Toolkit
Bean Validation API / JSR 303
CGLIB (Hibernate / Spring / JBoss /
 Apache Geronimo)
dom4j
EclipseLink
GeoTools
Google Guice
Groovy
GWT / javax.imageio
Hessian
iCal4J
Infinispan
IntrospectionUtils
 
JarURLConnection
Java Advanced Imaging (JAI)
Javassist
Java Cryptography Architecture (JCA)
Java Server Faces 2
javax.security.auth.Policy/login.Configuration
JGroups
Logback
JAXB
Mozilla Rhino
MVEL
OpenOffice Java Uno RunTime (JURT)
Oracle JDBC
RMI
Serialization (<= JDK 1.4.2)
Spring framework
Unified Expression Language / javax.el
URLConnection + HTTP 1.1
XML parsing (DocumentBuilderFactory)
Mattias Jiderhamn – java.jiderhamn.se
 
How?
Mattias Jiderhamn – java.jiderhamn.se
Leak Prevention Lib
 
Application server independent
Version 2 core module is pure Java SE!
Covers a lot more than Tomcat
System class references avoided/cleared
Threads are stopped
ThreadLocals are cleared
Known offenders handled
Logs warnings
Apache 2 licensed
You may modify and redistribute
Mattias Jiderhamn – java.jiderhamn.se
Leak Prevention Lib
 
Zero runtime dependencies
No required config
 
Maven 
pom.xml
 (Servlet 3.0+):
<
dependency
>
  <
groupId
>se.jiderhamn.classloader-leak-prevention</
groupId
>
  <
artifactId
>classloader-leak-prevention-servlet3</
artifactId
>
  <
version
>2.0.1</
version
>
</
dependency
>
Mattias Jiderhamn – java.jiderhamn.se
Tomcat
 
Bugzilla #48895
ThreadLocalMap
 
Thread
 
Cleanup
Thread
 
remove()
 
Unsafe!
 
get()
set()
remove()
 
Removed in 6.0.27
 
Tomcat 7.0.6+ renews the thread pool
whenever an application is redeployed.
Disposable threads for lifecycle events.
 
Bugzilla #49159
Mattias Jiderhamn – java.jiderhamn.se
Leak Prevention Lib
 
set(null)
ThreadLocalMap
Entry
 
Thread
ThreadLocal
Foo
 
Stale
 
Cleanup
Thread
Mattias Jiderhamn – java.jiderhamn.se
 
Open Source
examples
Mattias Jiderhamn – java.jiderhamn.se
Bean Validation API
 
Version 1.0.0.GA
javax.validation.Validation
Application Server
validation-api-1.0.0.GA.jar
app.war
hibernate-validator.jar
Mattias Jiderhamn – java.jiderhamn.se
javax.el API
 
javax.el.BeanELResolver
Mattias Jiderhamn – java.jiderhamn.se
Apache CXF
org.apache.cxf.transport.http.CXFAuthenticator
 
CXF-5442
Mattias Jiderhamn – java.jiderhamn.se
OpenOffice JURT
 
com.sun.star.lib.util.AsynchronousFinalizer
Mattias Jiderhamn – java.jiderhamn.se
 
Training!
Gear up!
Mattias Jiderhamn – java.jiderhamn.se
Free tool
Eclipse Memory Analyzer
aka MAT
eclipse.org/mat
Mattias Jiderhamn – java.jiderhamn.se
Heap dump
Run application server with
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/temp
Mattias Jiderhamn – java.jiderhamn.se
Links
Join the fight!
 
java.jiderhamn.se      
@mjiderhamn
github.com/mjiderhamn
ClassLoader Leak Prevention Library
Step by step guide: acquire heap
dump and analyze for leaks using
Eclipse Memory Analyzer (MAT)
List of known offenders and links to bug reports
Submit reports and pull requests!
???
Slide Note
Embed
Share

Memory issues can lead to errors like OutOfMemoryError, affecting Java applications. Learn about PermGen space, Metaspace, and JVM memory management to prevent leaks and optimize performance. Explore solutions and examples to tackle these challenges efficiently.

  • Java
  • Memory Management
  • Classloader Leaks
  • JVM Memory
  • OutOfMemoryError

Uploaded on Feb 23, 2025 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Join the war on Classloader leaks Mattias Jiderhamn Mattias Jiderhamn java.jiderhamn.se

  2. :-( java.lang.OutOfMemoryError: PermGen space Metaspace Mattias Jiderhamn java.jiderhamn.se

  3. Local dev env java.lang. OutOfMemoryError: Metaspace Mattias Jiderhamn java.jiderhamn.se

  4. Continuous Deploy java.lang. OutOfMemoryError: Metaspace .war Mattias Jiderhamn java.jiderhamn.se

  5. Agenda What does it mean? Why does it happen? Where does it leak? How to avoid? OSS examples Training! Mattias Jiderhamn java.jiderhamn.se

  6. What? Mattias Jiderhamn java.jiderhamn.se

  7. JVM memory PermGen / Metaspace Stack Heap Mattias Jiderhamn java.jiderhamn.se

  8. JVM memory Per thread Local variables and method parameters Stack Mattias Jiderhamn java.jiderhamn.se

  9. JVM memory Object instances Heap Young generation Eden space Old generation / tenured space Survivor space Mattias Jiderhamn java.jiderhamn.se

  10. JVM memory Permanent Generation PermGen / Metaspace java.lang.Class instances etc Named before JEE and class unloading Renamed Metaspace in Java 8 Aka Method area Mattias Jiderhamn java.jiderhamn.se

  11. What? java.lang.OutOfMemoryError: PermGen space / Metaspace = Too many classes are loaded Mattias Jiderhamn java.jiderhamn.se

  12. Why? Mattias Jiderhamn java.jiderhamn.se

  13. Reason for OOME java.lang.OutOfMemoryError: PermGen space / Metaspace 1. Your application is too large -XX:MaxPermSize=256M Java 8: Metaspace auto increase by default 2. java.lang.Class instances could not be garbage collected after redeploy Mattias Jiderhamn java.jiderhamn.se

  14. Reference types Strong (i.e. normal) reference Never GC:ed if reachable Soft reference GC:ed before OutOfMemoryError Weak reference (WeakHashMap) GC:ed when no Strong or Soft refs Phantom reference won t prevent GC Mattias Jiderhamn java.jiderhamn.se

  15. Example WeakHashMap Map m = new WeakHashMap(); Foo myFoo = new Foo(); m.put(myFoo, bar ); myFoo = null; Foo Mattias Jiderhamn java.jiderhamn.se

  16. GC reachability GC roots Mattias Jiderhamn java.jiderhamn.se

  17. Redeploy Application Server ClassLoader ClassLoader ClassLoader app.war app.war app.war Mattias Jiderhamn java.jiderhamn.se

  18. ClassLoader refs ClassLoader Class Class Class Instance Mattias Jiderhamn java.jiderhamn.se

  19. How leaks happen Application Server ClassLoader Class Class Class Instance GC root Mattias Jiderhamn java.jiderhamn.se

  20. Where? Mattias Jiderhamn java.jiderhamn.se

  21. Application Server Application Server bugs Logging frameworks Apache Commons Logging Unless LogFactory.release() Log4j - some configs Unless LogManager.shutdown() java.util.logging custom Level Bean Validation API (JSR 303) Unified Expression Language (javax.el) ? Mattias Jiderhamn java.jiderhamn.se

  22. GC roots Class loaded by system ClassLoader static field in JDK classes (java.* etc) Live thread Stack local vars, method params java.lang.Thread instance Object held as synchronization monitor JNI references JVM specials Mattias Jiderhamn java.jiderhamn.se

  23. System classes java.sql.DriverManager Bean introspection cache, shutdown hooks, custom default Authenticator, custom security Provider, custom MBeans, custom ThreadGroup, custom property editor, Reference tocontextClassLoader of first caller Mattias Jiderhamn java.jiderhamn.se

  24. DriverManager Mattias Jiderhamn java.jiderhamn.se

  25. DriverManager JRE Application Server DriverManager 1) ClassLoader com.mysql.jdbc.Driver app.war mysql-jdbc.jar or 2) DriverManager.deregisterDriver( ) Mattias Jiderhamn java.jiderhamn.se

  26. Context shutdown public class MyCleanupListener implements javax.servlet.ServletContextListener { ... /** Called when application is undeployed */ public void contextDestroyed( ServletContextEvent servletContextEvent) { DriverManager.deregisterDriver( ); } } Mattias Jiderhamn java.jiderhamn.se

  27. Threads Thread stack Local variables Method parameters MyThread extends Thread MyRunnable implements Runnable contextClassLoader + AccessControlContext inherited Example HTTP 1.1 Keep-Alive-Timer Mattias Jiderhamn java.jiderhamn.se

  28. Context shutdown public class MyCleanupListener implements javax.servlet.ServletContextListener { ... /** Called when application is undeployed */ public void contextDestroyed( ServletContextEvent servletContextEvent) { DriverManager.deregisterDriver( ); // Stop threads here! } } Mattias Jiderhamn java.jiderhamn.se

  29. Stopping threads public class MyThread extends Thread { public void run() { while(true) { // Bad idea! // Do something } } } Mattias Jiderhamn java.jiderhamn.se

  30. Stopping threads public class MyThread extends Thread { private boolean running = true; private volatile boolean running = true; public void run() { while(running) { // Until stopped // Do something } } public void shutdown() { running = false; } Heinz Kabutz / Java Specialists - The Law of the Blind Spot } Mattias Jiderhamn java.jiderhamn.se

  31. Threads Thread stack Local variables Method parameters MyThread extends Thread MyRunnable implements Runnable contextClassLoader + AccessControlContext inherited Example HTTP 1.1 Keep-Alive-Timer ThreadLocal Mattias Jiderhamn java.jiderhamn.se

  32. ThreadLocal X X ThreadLocal WeakHashMap<Thread, ?> Foo Thread Mattias Jiderhamn java.jiderhamn.se

  33. ThreadLocal ThreadLocal JavaDoc: Each thread holds an implicit reference to its copy of a thread- local variable as long as the thread is alive and the ThreadLocal instance is accessible; Mattias Jiderhamn java.jiderhamn.se

  34. ThreadLocal Thread ThreadLocalMap Entry put() ThreadLocal Foo set() Mattias Jiderhamn java.jiderhamn.se

  35. (?) ThreadLocal Pooled threads: Threads may outlive ClassLoader ThreadLocal ThreadGlobal! Mattias Jiderhamn java.jiderhamn.se

  36. ThreadLocal Thread ThreadLocalMap Entry ThreadLocal Foo static Class ClassLoader Class Mattias Jiderhamn java.jiderhamn.se

  37. ThreadLocal Thread ThreadLocalMap Entry Stale entry ThreadLocal Foo ClassLoader Class Mattias Jiderhamn java.jiderhamn.se

  38. ThreadLocal ThreadLocalMap JavaDoc: However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space Mattias Jiderhamn java.jiderhamn.se

  39. ThreadLocal Custom value (incl references) static ThreadLocal = leak otherwise = unpredicted GC Custom ThreadLocal = no leak Mattias Jiderhamn java.jiderhamn.se

  40. ThreadLocal Always clear your ThreadLocals! try { myThreadLocal.set(foo); } finally { myThreadLocal.remove(); } Mattias Jiderhamn java.jiderhamn.se

  41. Known offenders Apache ActiveMQ Apache Axis Apache Batik Apache Commons Pool / DBCP Apache CXF AWT Toolkit Bean Validation API / JSR 303 CGLIB (Hibernate / Spring / JBoss / Apache Geronimo) dom4j EclipseLink GeoTools Google Guice Groovy GWT / javax.imageio Hessian iCal4J Infinispan IntrospectionUtils JarURLConnection Java Advanced Imaging (JAI) Javassist Java Cryptography Architecture (JCA) Java Server Faces 2 javax.security.auth.Policy/login.Configuration JGroups Logback JAXB Mozilla Rhino MVEL OpenOffice Java Uno RunTime (JURT) Oracle JDBC RMI Serialization (<= JDK 1.4.2) Spring framework Unified Expression Language / javax.el URLConnection + HTTP 1.1 XML parsing (DocumentBuilderFactory) Mattias Jiderhamn java.jiderhamn.se

  42. How? Mattias Jiderhamn java.jiderhamn.se

  43. Leak Prevention Lib Application server independent Version 2 core module is pure Java SE! Covers a lot more than Tomcat System class references avoided/cleared Threads are stopped ThreadLocals are cleared Known offenders handled Logs warnings Apache 2 licensed You may modify and redistribute Mattias Jiderhamn java.jiderhamn.se

  44. Leak Prevention Lib Zero runtime dependencies No required config Maven pom.xml (Servlet 3.0+): <dependency> <groupId>se.jiderhamn.classloader-leak-prevention</groupId> <artifactId>classloader-leak-prevention-servlet3</artifactId> <version>2.0.1</version> </dependency> Mattias Jiderhamn java.jiderhamn.se

  45. Tomcat Cleanup Thread Thread get() set() remove() remove() ThreadLocalMap Unsafe! Removed in 6.0.27 Bugzilla #48895 Tomcat 7.0.6+ renews the thread pool whenever an application is redeployed. Disposable threads for lifecycle events. Bugzilla #49159 Mattias Jiderhamn java.jiderhamn.se

  46. Leak Prevention Lib Cleanup Thread Thread set(null) ThreadLocalMap Entry Stale Foo ThreadLocal Mattias Jiderhamn java.jiderhamn.se

  47. Open Source examples Mattias Jiderhamn java.jiderhamn.se

  48. Bean Validation API Version 1.0.0.GA javax.validation.Validation Application Server validation-api-1.0.0.GA.jar app.war hibernate-validator.jar Mattias Jiderhamn java.jiderhamn.se

  49. javax.el API javax.el.BeanELResolver Mattias Jiderhamn java.jiderhamn.se

  50. Apache CXF org.apache.cxf.transport.http.CXFAuthenticator CXF-5442 Mattias Jiderhamn java.jiderhamn.se

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#