gpt4 book ai didi

java - Java 堆栈跟踪中的 "eliminated"是什么意思?

转载 作者:IT老高 更新时间:2023-10-28 21:02:02 26 4
gpt4 key购买 nike

我正在查看我的 Java 应用程序的线程转储,并注意到有时我看到关键字“已消除”而不是显示“锁定”,如下所示:

"Worker [4]" prio=10 tid=0x00007fb1262d8800 nid=0x89a0 in Object.wait() [0x00007fb15b147000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at com.myapp.common.util.WaitableQueue.getAll(WaitableQueue.java:152)
- eliminated <0x00000004d0d28e18> (a com.myapp.common.util.balq.SingleQueueQController$_WorkerQueue)
at com.myapp.common.util.balq.SingleQueueQController$_WorkerQueue.getAll(SingleQueueQController.java:3527)
- locked <0x00000004d0d28e18> (a com.myapp.common.util.balq.SingleQueueQController$_WorkerQueue)
at com.myapp.common.util.AbstractWorker.read(AbstractWorker.java:678)
at com.myapp.common.util.AbstractWorker.runBulk(AbstractWorker.java:541)
at com.myapp.common.util.AbstractWorker.run(AbstractWorker.java:343)

令人惊讶的是,我在 Google 上找不到任何关于此的信息。 “锁定”和“消除”关键字有什么区别?

最佳答案

它表示字节码中已删除的冗余锁。

我总是发现源代码是一个很好的起点。来自 openJDK 的 hotspot/src/share/vm/opto/callnode.cpp 的评论有以下有趣的评论:

// Redundant lock elimination
//
// There are various patterns of locking where we release and
// immediately reacquire a lock in a piece of code where no operations
// occur in between that would be observable. In those cases we can
// skip releasing and reacquiring the lock without violating any
// fairness requirements. Doing this around a loop could cause a lock
// to be held for a very long time so we concentrate on non-looping
// control flow. We also require that the operations are fully
// redundant meaning that we don't introduce new lock operations on
// some paths so to be able to eliminate it on others ala PRE. This
// would probably require some more extensive graph manipulation to
// guarantee that the memory edges were all handled correctly.
//
// Assuming p is a simple predicate which can't trap in any way and s
// is a synchronized method consider this code:
//
// s();
// if (p)
// s();
// else
// s();
// s();
//
// 1. The unlocks of the first call to s can be eliminated if the
// locks inside the then and else branches are eliminated.
//
// 2. The unlocks of the then and else branches can be eliminated if
// the lock of the final call to s is eliminated.
//
// Either of these cases subsumes the simple case of sequential control flow

因此,从上面看来(至少在 openJDK 中),消除意味着锁是由 JVM 通过一组或多组释放/获取指令来维护的。

查看 hotspot/src/share/vm/runtime/vframe.cpp 中的 javaVFrame::print_lock_info_on() 会显示检查和输出发生的位置:

// Print out all monitors that we have locked or are trying to lock
GrowableArray<MonitorInfo*>* mons = monitors();
if (!mons->is_empty()) {
bool found_first_monitor = false;
for (int index = (mons->length()-1); index >= 0; index--) {
MonitorInfo* monitor = mons->at(index);
if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code
if (monitor->owner_is_scalar_replaced()) {
Klass* k = Klass::cast(monitor->owner_klass());
st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name());
} else {
oop obj = monitor->owner();
if (obj != NULL) {
print_locked_object_class_name(st, obj, "eliminated");
}
}
continue;

包括上述评论在内的其他评论也暗示将锁定和解锁指令替换为 NOP。

我阅读了 Dirk 提到的关于 lock elision 的文档。它似乎是 Lock Coarsening 而不是 Elision:

Another optimization that can be used to reduce the cost of locking is lock coarsening. Lock coarsening is the process of merging adjacent synchronized blocks that use the same lock object. If the compiler cannot eliminate the locking using lock elision, it may be able to reduce the overhead by using lock coarsening.

但老实说,区别非常细微,最终效果几乎相同 - 您消除了不必要的锁定和解锁。

关于java - Java 堆栈跟踪中的 "eliminated"是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21631052/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com