JVM中对java.lang.ref.Reference$Lock上的数组分配的大量锁
我们使用Java Flight Recorder评测应用程序,并在Java.lang.ref.Reference$Lock对象上发现了大量锁 我调查了stacktraces中的一些地方,发现在所有情况下都存在数组分配 代码示例(图像上的位置3):JVM中对java.lang.ref.Reference$Lock上的数组分配的大量锁,java,performance,garbage-collection,locking,jfr,Java,Performance,Garbage Collection,Locking,Jfr,我们使用Java Flight Recorder评测应用程序,并在Java.lang.ref.Reference$Lock对象上发现了大量锁 我调查了stacktraces中的一些地方,发现在所有情况下都存在数组分配 代码示例(图像上的位置3): public static char[]copyOfRange(char[]original,int-from,int-to){ int newLength=to-from; if(newLength”+到); //在下一行堆叠跟踪点 char[]c
public static char[]copyOfRange(char[]original,int-from,int-to){
int newLength=to-from;
if(newLength<0)
抛出新的IllegalArgumentException(从+“>”+到);
//在下一行堆叠跟踪点
char[]copy=new char[newLength];
System.arraycopy(原件、原件、副本、0、,
Math.min(original.length-from,newLength));
返回副本;
}
我怀疑这种锁定与GC有关,但找不到任何相关信息。
我在哪里可以阅读更多关于这个主题的内容
活动的最终目标:了解在这种情况下PAPPENING是什么,影响PAPPENING的因素,以及我们如何减少此类操作的锁定时间
评论中的一些细节:
Java Flight Recorder的一大缺点是它只显示Java堆栈,完全忽略了本机和VM部分 从这个意义上讲更准确。如果在启用本机堆栈的情况下以
lock
评测模式运行它,它将显示获取这些锁的确切位置。命令示例:
./profiler.sh -d 60 -e lock --cstack fp -f profile.html -o flamegraph=total PID
运行分析60秒-d 60
配置文件锁争用-e lock
记录C(本机)堆栈--cstack fp
输出文件名(async profiler 2.0中的html格式,或1.x中的SVG)-f profile.html
使用总锁等待时间作为计数器构建火焰图-o flamegraph=total
Java进程IDPID
引用$lock
实例上的锁争用。堆栈跟踪的Java部分显示为绿色。这与您在JFR中看到的堆栈跟踪相匹配。与您的示例一样,顶部的Java框架是Arrays.copyOfRange
(图中还显示了其他堆栈,但让我们关注第一个堆栈)
黄色部分是本机C++代码。让我解释一下那里发生了什么
array.copyOfRange
调用VM运行时函数OptoRuntime::new_array\u nozero\u C
。实际的数组分配发生在JVM的C++代码中。
ReferenceHandler
线程在GC启动之前离开关键部分。在持有此锁的同时,JVM可以安全地将新发现的弱引用附加到挂起列表
Reference$Lock
上的争用本身不是问题。在GC回收足够的内存之前,分配线程无论如何都无法继续。实际问题是,并发垃圾收集跟不上分配速率
要缓解此问题,请尝试以下一种或多种方法:
- 增加堆的大小李>
- 降低分配率李>
- 增加并发GC线程的数量-
李>congcthreads
- 降低
以更早地启动并发GC循环李>启动eapOccupencyPercent
显示占用最多cpu时间的内容。Java和VM线程一起显示在同一个图上,因此您可以了解GC活动相对于应用程序工作是否过高-e cpu
显示分配最多的代码。在研究如何降低分配率时,它特别有用-e alloc