-
Bug
-
Resolution: Fixed
-
P3
-
8, 11, 17, 18
-
b09
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8284385 | 18.0.2 | Roman Kennke | P3 | Resolved | Fixed | b02 |
JDK-8282806 | 18.0.1 | Roman Kennke | P3 | Resolved | Fixed | b10 |
JDK-8287345 | 17.0.5-oracle | Alex Menkov | P3 | Resolved | Fixed | b01 |
JDK-8282808 | 17.0.4 | Roman Kennke | P3 | Resolved | Fixed | b01 |
JDK-8287188 | 11.0.17-oracle | Alex Menkov | P3 | Resolved | Fixed | b01 |
JDK-8282807 | 11.0.16 | Roman Kennke | P3 | Resolved | Fixed | b01 |
https://bugzilla.redhat.com/show_bug.cgi?id=2010221
We observe a native memory leak when repeating JDI operations from Eclipse in a debuggee JVM.
jemalloc reports the biggest memory leak as:
[76800 bytes leaked]
je_prof_backtrace (/home/sandreev/git/misc/jemalloc/src/prof.c:636 (discriminator 2))
je_malloc_default (/home/sandreev/git/misc/jemalloc/src/jemalloc.c:2289)
os::malloc (/data/git/jdk11/src/hotspot/share/runtime/os.cpp:697)
os::malloc (/data/git/jdk11/src/hotspot/share/runtime/os.cpp:660 (discriminator 3))
JvmtiEnvBase::allocate (/data/git/jdk11/src/hotspot/share/prims/jvmtiEnvBase.hpp:195)
JvmtiEnvBase::jvmtiMalloc (/data/git/jdk11/src/hotspot/share/prims/jvmtiEnvBase.cpp:501)
JvmtiEnv::GetMethodName (/data/git/jdk11/src/hotspot/share/prims/jvmtiEnv.cpp:2954)
jvmti_GetMethodName (/data/git/jdk11/build/linux-x86_64-normal-server-slowdebug/hotspot/variant-server/gensrc/jvmtifiles/jvmtiEnter.cpp:4366)
methodSignature (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/util.c:728)
fillInvokeRequest (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c:284)
invoker_requestInvoke (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c:371)
sharedInvoke (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/util.c:609)
invokeStatic (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/ClassTypeImpl.c:175)
debugLoop_run (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c:159)
connectionInitiated (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/transport.c:296)
attachThread (/data/git/jdk11/src/jdk.jdwp.agent/share/native/libjdwp/transport.c:370)
JvmtiAgentThread::call_start_function (/data/git/jdk11/src/hotspot/share/prims/jvmtiImpl.cpp:85)
JvmtiAgentThread::start_function_wrapper (/data/git/jdk11/src/hotspot/share/prims/jvmtiImpl.cpp:79)
JavaThread::thread_main_inner (/data/git/jdk11/src/hotspot/share/runtime/thread.cpp:1752)
JavaThread::run (/data/git/jdk11/src/hotspot/share/runtime/thread.cpp:1732)
thread_native_entry (/data/git/jdk11/src/hotspot/os/linux/os_linux.cpp:698)
start_thread (/usr/src/debug/glibc-2.17-c758a686/nptl/pthread_create.c:308)
?? (/usr/src/debug////////glibc-2.17-c758a686/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:113)
How reproducible:
Run JDI operations with Eclipse in any Java program. E.g. can be done with a command handler:
public class SampleHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Job job = new Job("JDI operation") {
@Override
protected IStatus run(IProgressMonitor monitor) {
int n = 20 * 60;
for (int i = 0; i < n; ++i) {
try {
IJavaDebugTarget javaTarget = getFirstJavaDebugTarget();
if (javaTarget != null) {
IJavaThread javaThread = getFirstSuspendedJavaThread(javaTarget);
if (javaThread != null) {
IJavaType[] javaClass = javaTarget.getJavaTypes("java.lang.String");
if (javaClass[0] instanceof IJavaClassType) {
IJavaClassType jdiClassType = (IJavaClassType) javaClass[0];
IJavaObject instance = jdiClassType.newInstance("()V", null, javaThread);
try {
instance.disableCollection();
if (!monitor.isCanceled()) {
instance.sendMessage("isEmpty", "()Z", null, javaThread, false);
}
} finally {
instance.enableCollection();
}
}
}
}
} catch (DebugException e) {
e.printStackTrace();
}
}
return Status.OK_STATUS;
}
};
job.schedule();
return null;
}
private IJavaDebugTarget getFirstJavaDebugTarget() {
for (IDebugTarget debugTarget : DebugPlugin.getDefault().getLaunchManager().getDebugTargets()) {
if (debugTarget instanceof IJavaDebugTarget) {
return (IJavaDebugTarget) debugTarget;
}
}
return null;
}
private IJavaThread getFirstSuspendedJavaThread(IJavaDebugTarget javaDebugTarget) throws DebugException {
for (IThread thread : javaDebugTarget.getThreads()) {
if (thread.isSuspended() && (thread instanceof IJavaThread)) {
return (IJavaThread) thread;
}
}
return null;
}
}
Actual results:
Memory consumption of debuggee JVM increases as JDI operations are repeated.
Expected results:
No memory is leaked by fillInvokeRequest() in invoker.c.
- backported by
-
JDK-8282806 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
-
JDK-8282807 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
-
JDK-8282808 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
-
JDK-8284385 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
-
JDK-8287188 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
-
JDK-8287345 Memory leak in invoker.c fillInvokeRequest() during JDI operations
- Resolved
- links to
-
Commit openjdk/jdk11u-dev/4b9bba66
-
Commit openjdk/jdk17u-dev/e2103de4
-
Commit openjdk/jdk18u/16ff0561
-
Commit openjdk/jdk/5ab22e88
-
Review openjdk/jdk11u-dev/852
-
Review openjdk/jdk17u-dev/192
-
Review openjdk/jdk18u/32
-
Review openjdk/jdk/7306