-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When logging exceptions, the exception stack traces include dynamically generated class names, which leads to a memory leak. #3282
Comments
@alan0428a, do you have time to look at this issue? Maybe we should start with writing a test, ideally that doesn't require an OOM. |
I can reproduce the issue with a simple: for (int i = 0; ; i++) {
try {
Class.forName(Main.class.getName() + i);
} catch (ClassNotFoundException e) {
// ignore
}
} This has apparently been reported as JDK-8037342, but has been classified as I am not sure there is anything we can do to workaround this JDK bug: if you want packaging information in your stack traces (the trailing <PatternLayout pattern="%d [%t] %p %c{.} - %m%n%ex"/> |
Nice reproducer @ppkarwasz ! |
@vy Sorry, I can't find the version 2.25.0-SNAPSHOT in the Maven repository. It seems that this version has not been released to the Maven repository yet. |
@ppkarwasz This is a rather hidden problem. We didn't realize that we should pay attention to this point when using Log4j to output exception information until we located the cause of the problem. Of course, it's a low-probability event and only occurs when used in combination with certain special libraries. However, once it occurs, it's still quite difficult to troubleshoot this problem. It took two months from the startup of our system to the occurrence of Out Of Memory (OOM). The loadClass method is called internally within Log4j. I wonder if there should be some mechanism that can monitor and alert users when too many different classes have been loaded, making this problem easier to expose. |
As mentioned by @vy, in
|
@ppkarwasz , Currently, it seems there isn't a perfect solution to prevent this problem in advance; we can only address it after the issue is discovered. |
@ppkarwasz, shall we document this unexpected behavior of |
Sure, let us document it in the |
@ppkarwasz @vy |
Yes, currently |
Description
When using the Nashorn JavaScript engine, if an exception is thrown internally within the JavaScript code and this exception is logged using a logger, it results in a memory leak. Tracing the log4j source code reveals that log4j uses
ThrowableProxy
when handling exception parameters.ThrowableProxy
callsloadClass
. Because Nashorn dynamically generates some classes, the exception stack trace includes dynamically generated class names, which are not cached. This causes loadClass to add these class names to theparallelLockMap
inside the ClassLoader, leading to a memory leak.Configuration
Version: 2.24.1
Operating system: Windows10
JDK: 1.8.0_331
Logs
Below are some log fragments. Note the class names in the exception stack trace that follow the pattern
jdk.nashorn.internal.scripts.Script$Recompilation$19663$15$^eval_.test.
The numbers following Recompilation$ are incrementing.Reproduction
Below is my test case, with memory settings configured as -Xms10m -Xmx10m. The program runs for 2 minutes and 24 seconds before an OutOfMemoryError (OOM) occurs.
The text was updated successfully, but these errors were encountered: