-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b130
-
Not verified
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The thread created by the GC class does not explicitly set the context
class loader so it inherits the current context class loader.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Consider the following sequence where each module has a dedicated class loader (e.g. web applications in a Servlet container).
Module A starts an RMIConnectorServer instance. Amongst other things it
calls GC.requestLatency(long) which starts the Daemon thread.
Module B starts another RMIConnectorServer instance. It also calls
GC.requestLatency(long) and the Daemon thread continues.
Module A shuts down the RMIConnectorServer and does all the right
clean-up. The associated LatencyRequest is cancelled but the Daemon
thread continues because of the LatencyRequest from Module B.
At this point there is a memory leak because the class loader associated
with module A is pinned in memory since a reference to it is held by the
context class loader field of the Daemon thread.
The fix looks to be trivial. Something along the lines of the following
around line 146 of GC:
d.setContextClassLoader(GC.class.getClassLoader());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class loader from module A is eligible for GC.
ACTUAL -
The class loader from module A is not eligible for GC.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
https://github.com/markt-asf/memory-leaks/blob/master/src/org/apache/markt/leaks/rmi/GcThreadLeak.java
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Trigger the creation of the thread with a thread context class loader than is never going to be eligible for GC.
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The thread created by the GC class does not explicitly set the context
class loader so it inherits the current context class loader.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Consider the following sequence where each module has a dedicated class loader (e.g. web applications in a Servlet container).
Module A starts an RMIConnectorServer instance. Amongst other things it
calls GC.requestLatency(long) which starts the Daemon thread.
Module B starts another RMIConnectorServer instance. It also calls
GC.requestLatency(long) and the Daemon thread continues.
Module A shuts down the RMIConnectorServer and does all the right
clean-up. The associated LatencyRequest is cancelled but the Daemon
thread continues because of the LatencyRequest from Module B.
At this point there is a memory leak because the class loader associated
with module A is pinned in memory since a reference to it is held by the
context class loader field of the Daemon thread.
The fix looks to be trivial. Something along the lines of the following
around line 146 of GC:
d.setContextClassLoader(GC.class.getClassLoader());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class loader from module A is eligible for GC.
ACTUAL -
The class loader from module A is not eligible for GC.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
https://github.com/markt-asf/memory-leaks/blob/master/src/org/apache/markt/leaks/rmi/GcThreadLeak.java
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Trigger the creation of the thread with a thread context class loader than is never going to be eligible for GC.
- duplicates
-
JDK-8160513 ClassNotFoundException sun.misc.GC when running Tomcat 9 with JDK 9
- Closed
- relates to
-
JDK-8172726 ForkJoin common pool retains a reference to the thread context class loader
- Resolved