On Mon, 5 Aug 2024 00:32:40 GMT, leo liang <d...@openjdk.org> wrote: > Hi there, we are seeing this issue when we run JFR on our services under > load, we see a large spike of CPU after JFR is triggered, which cause 500 > errors in our service. We are currently using corretto-17 in our service. > > Wondering this fix get back ported to JDK 17? As I can't find this change > mentioned in [JDK > update](https://wiki.openjdk.org/display/JDKUpdates/Archived+Releases) or in > [jdk17u tag > compare](https://github.com/openjdk/jdk17u/compare/jdk-17.0.9+9...jdk-17.0.13+1) > > Also, wondering if there is a walk around for this issue if the PR is not > back ported to Java 17. `XX:+EnableDynamicAgentLoading` seems to only > supported in Java 21, so that wouldn't help for now
@leomao10, I'm not sure if this change will ever be downported to older releases like JDK 21 or even JDK 17. I personally consider it low risk, but there have been reports of performance regressions in some cases (e.g. [JDK-8336805](https://bugs.openjdk.org/browse/JDK-8336805)). I couldn't reproduce them, but I can image that they will make the maintainers of LTS releases even more cautious. The easiest way to workaround this issue in JDK 17 would be to set the `can_redefine_classes`, `can_retransform_classes` or `can_generate_breakpoint_events` JVMTI capabilities at startup or early in the lifetime of the JVM. There are several ways how you could do this. - trigger JFR right after startup. This will still invalidate all the JIT compiled methods but if you do this early enough there won'T be many of them. After you've triggered JFR for the first time, the corresponding JVMTI capabilities will be set and all dependencies will be recorded automatically so any subsequent JFR invocation won't suffer from a performance degradation any more. - attach any other JVMTI agent like for example [async profiler](https://github.com/async-profiler/async-profiler) which requests the corresponding JVMTI capabilities at startup. - write your own, trivial JVMTI agent which merely requests the corresponding JVMTI capabilities and attach it at startup with `agentpath:jvmtiAgent.so`. The agent can be as simple as: /* g++ -fPIC -shared -I $JAVA_HOME/include/ -I $JAVA_HOME/inlude/linux -o jvmtiAgent.so jvmtiAgent.cpp */ #include <jvmti.h> #include <stdio.h> #include <string.h> extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* jvm, char* options, void* reserved) { jvmtiEnv* jvmti = NULL; jvmtiCapabilities capa; jvmtiError error; jint result = jvm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_1); if (result != JNI_OK) { fprintf(stderr, "Can't access JVMTI!\n"); return JNI_ERR; } memset(&capa, 0, sizeof(jvmtiCapabilities)); capa.can_redefine_classes = 1; capa.can_retransform_classes = 1; capa.can_generate_breakpoint_events = 1; if (jvmti->AddCapabilities(&capa) != JVMTI_ERROR_NONE) { fprintf(stderr, "Can't set capabilities!\n"); return JNI_ERR; } else { fprintf(stdout, "Added capabilities!\n"); } return JNI_OK; } ------------- PR Comment: https://git.openjdk.org/jdk/pull/17509#issuecomment-2346646666