当应用程序与JAVA代理(-javaagent)一起运行时,代理旧有可能使用JVMTI标记堆中的对象。代理可以出于各种原因使用JVMTI进行对象标记,但是如果标记大量的对象,那么GC的性能就会收到影响,从而影响到应用程序的性能。
这个问题存在于本地代码中,其中JvmtiTagMap::do_weak_oops在每个垃圾收集事件期间遍历所有JVMTI标记的对象,并对所有JVMTI标记的对象执行开销不大的操作。更糟糕的是这个操作是顺序执行的不是并行的。
当存在大量的JVMTI标记对象时,这意味着GC过程大部分时间是在单线程中执行的,潜在地增加了一个数量级的GC暂停时间。
要检查指定代理是否会导致延长GC暂停时间,你需要打开诊断选项-XX:+UnlockDiagnosticVMOptions -XX:+TraceJVMTIObjectTagging,可以侦测并估计tag map消耗了多少本机内存,以及遍历这些对象花费了多长时间。
通常你也做不了什么,只能给代理商提建议,修复这种问题。
参考《Plumbr Handbook Java 》