-
Bug
-
Resolution: Unresolved
-
P4
-
17, 21, 26
This was initially reported as an Async-Profiler bug: https://github.com/async-profiler/async-profiler/issues/1453
However, it can be reproduced with a relatively simple setup: https://github.com/fandreuz/jdk-stuff/tree/master/repro-asprof-1453
The outcome is a full Code Cache, so the compiler is disabled:
[6.420s][warning][codecache] CodeCache is full. Compiler has been disabled.
[6.420s][warning][codecache] Try increasing the code cache size using -XX:ReservedCodeCacheSize=
CodeCache: size=10240Kb used=10239Kb max_used=10239Kb free=0Kb
bounds [0x00007f3df687c000, 0x00007f3df727c000, 0x00007f3df727c000]
total_blobs=12158, nmethods=11858, adapters=214, full_count=1
Compilation: disabled (not enough contiguous free space left), stopped_count=1, restarted_count=0
JNI::RegisterNatives allows assigning an arbitrary address to a native Java function. The previous nmethod (if present) is made not entrant (Method::set_native_function). However, the definition of nmethod::is_cold() prevents the previous nmethod instance from ever being reclaimed by GC, since it never becomes cold:
bool nmethod::is_cold() {
if (!MethodFlushing || is_native_method() || is_not_installed()) {
// No heuristic unloading at all
return false;
}
The check for "is_native_method()" was initially introduced inJDK-4360113 with the comment "Also, don't flush native methods since they are part of the JDK in most cases".
The check has never been touched afterwards,JDK-8290025 moved the logic into nmethod.cpp from sweeper.cpp. So, this behavior applies to all JDK versions since when nmethod eviction has been introduced. I tested it with 17, 21 and the current jdk master.
However, it can be reproduced with a relatively simple setup: https://github.com/fandreuz/jdk-stuff/tree/master/repro-asprof-1453
The outcome is a full Code Cache, so the compiler is disabled:
[6.420s][warning][codecache] CodeCache is full. Compiler has been disabled.
[6.420s][warning][codecache] Try increasing the code cache size using -XX:ReservedCodeCacheSize=
CodeCache: size=10240Kb used=10239Kb max_used=10239Kb free=0Kb
bounds [0x00007f3df687c000, 0x00007f3df727c000, 0x00007f3df727c000]
total_blobs=12158, nmethods=11858, adapters=214, full_count=1
Compilation: disabled (not enough contiguous free space left), stopped_count=1, restarted_count=0
JNI::RegisterNatives allows assigning an arbitrary address to a native Java function. The previous nmethod (if present) is made not entrant (Method::set_native_function). However, the definition of nmethod::is_cold() prevents the previous nmethod instance from ever being reclaimed by GC, since it never becomes cold:
bool nmethod::is_cold() {
if (!MethodFlushing || is_native_method() || is_not_installed()) {
// No heuristic unloading at all
return false;
}
The check for "is_native_method()" was initially introduced in
The check has never been touched afterwards,