`OutOfMemoryError: Metaspace` rises after repeated redeployments in Tomcat. Why?
advancedEach redeploy creates a new web-app class loader. If anything outside it keeps a reference to a class or object from the old loader (a ThreadLocal, a JDBC driver registered in DriverManager, a thread, a shutdown hook), the old loader and all its classes stay in Metaspace.
- Heap dump: find multiple instances of
WebappClassLoaderand trace the GC root path. - Use
jcmd <pid> VM.classloader_statsandGC.class_stats. - Fix: deregister drivers, stop threads, clear
ThreadLocals incontextDestroyed; do not hot-redeploy in production.
⚠ Follow-up traps
- Is Metaspace unlimited by default? Yes, so it grows until the container or OS limit; cap it with
-XX:MaxMetaspaceSize. - Do dynamically generated proxies matter? Yes, per-call
Proxy/CGLIB class generation inflates Metaspace.