Our developers noticed a memory leak with Method::ensure_jmethod_ids for a longer running application. The allocated JNIMethodBlockNodes are not freed after the associated user defined class loaders are unloaded. The daily leak is ~20MiB - ~70MiB. Please see the initial discussion in https://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2021-January/044946.html. The following comments in
https://github.com/openjdk/jdk/blob/379376f0783facba93e1d11db9b184ef8183a13b/src/hotspot/share/classfile/classLoaderData.cpp#L697 indicate the leak is intentional:
// Clear all the JNI handles for methods
// These aren't deallocated and are going to look like a leak, but that's
// needed because we can't really get rid of jmethodIDs because we don't
// know when native code is going to stop using them. The spec says that
// they're "invalid" but existing programs likely rely on their being
// NULL after class unloading.
Our attempted fix (https://github.com/openjdk/jdk/commit/66ef04af110862a1a6b727f12ad5eed9c26cd5a9) ran into SEGV crash in production environment when a profiler agent was enabled. The agent captured stack traces and then symbolized methods using jmethod_ids at a later point during runtime execution, which could happen after unloading the associated classes and loaders.
Further investigations have not yet found a more suitable approach than the existing one in Hotspot, which sets jmethod_ids to NULL instead of freeing the related memory during unloading. The existing approach mostly like was selected when considering the trade-off among stability, complexity and memory usage (although no additional background information has been located).
This bug is created to further clarify the comments in ClassLoaderData::~ClassLoaderData() for Method::clear_jmethod_ids() to explain why it is unsafe to release jmethod_id memory.