在Java堆栈跟踪中“消除”是什么意思?

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

"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替换锁定和解锁指令。

我阅读了关于lock elision的Dirk文件,似乎是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.

但是说实话,区别是非常微妙的,最终的效果是几乎相同的 – 你消除不必要的锁和解锁。

http://stackoverflow.com/questions/21631052/what-does-eliminated-mean-in-a-java-stack-trace

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在Java堆栈跟踪中“消除”是什么意思?