With respect to the specific issue
brought up in
https://youtrack.jetbrains.com/issue/JBR-1611:
"If we look into the code, we'll see that whenever a new class
is loaded and an event about it is delivered, when a garbage
collection has occurred, classTrack_processUnloads iterates
over all loaded classes to see if any of them have been
unloaded. This leads to O(classCount * gcCount) performance,
which in case of frequent GCs (and they are frequent,
especially the minor ones) is close to O(classCount^2). In
IDEA, we have quite a lot of classes, especially counting all
lambdas, so this results in quite significant overhead."
The debug agent calls JVMTI GetLoadedClasses() during
initialization to get a cache of all prepared classes. It
keeps that cache up-to-date by getting JVMTI CLASS_PREPARE
events. When there is a gc, the debug agent basically throws
away the cache and creates a new one by calling
GetLoadedClasses() again. It also compares the old and new
caches to determine which classes where unloaded, and
generates JDWP CLASS_UNLOAD events for them (if there is a
debugger attached that wants them).
It might be possible to defer initialization of the loaded
classes cache (and any maintenance of it) until there is a
debugger attached. I'm not sure if the only reason for the
cache is for delivery of CLASS_UNLOAD events, but at first
glance that appears to be the case.
Chris
On 6/20/19 1:31 PM, Volker Simonis wrote:
yes, I‘d say this is something well known. The
reason for this is that a debugging agent will request some
JVMTI capabilities like "can_access_local_variables" which
can only be requested at JVM startup. However, once these
capabilities have been taken, certain kinds of optimizations
like for example Escape Analysis, can’t be done anymore
which results in a performance degradation even if you don’t
ever attach a debugger.
We‘ve always enabled debugging in our
commercial SAP JVM and called it „Debugging on Demand“ but
usually didn’t observed any performance slowdown of more
than 3-5% at most. We’ve started contributing some of the
improvements we’ve done to make this possible to the
OpenJDK.
I’ve not looked into your concrete class
loading use case. Maybe it’s possible to improve that. First
you have to check by which JVMTI capability it is triggered
and if that capability is really necessary for debugging and
can only be requested at startup. If the answer is yes, you
can still check if it’s not possible to improve the
implementation of that capability in order to get a better
runtime behavior.
Regards,
Volker
Hi
everyone!
we have detected that a process started with the debug
agent (even when
debugger is not actually attached) may run significantly
slower than
without the agent, see:
https://youtrack.jetbrains.com/issue/JBR-1611
We all thought that without the debugger attached there
should not be a
difference.
Is that something well known? Should we file a bug?
Thanks,
Egor
--
Egor Ushakov
Software Developer
JetBrains
http://www.jetbrains.com
The Drive to Develop