我正在尝试调试Hadoop中的性能问题,其中一部分是我几次从不同的hadoop构建中捕获jstack,并在不同的Java版本上运行。当我的性能问题显现时,我得到了一个可运行线程的jstack,如下所示:

"DataXceiver for client DFSClient_NONMAPREDUCE_-619388227_1 at /x.x.x.x:35518 [Sending block BP-1509854702-x.x.x.x-1392815592442:blk_3738093208_1102227094469]" daemon prio=10 tid=0x00007f1a683cf800 nid=0xb61d1 runnable [0x00007f1a36060000]
   java.lang.Thread.State: RUNNABLE
    at org.apache.hadoop.hdfs.util.FoldedTreeSet.get(FoldedTreeSet.java:449)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.ReplicaMap.get(ReplicaMap.java:111)
    - locked <0x0000000751682590> (a org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.ReplicaMap.get(ReplicaMap.java:89)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.getVolume(FsDatasetImpl.java:177)
    - locked <0x0000000751682590> (a org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.getVolume(FsDatasetImpl.java:127)
    at org.apache.hadoop.hdfs.server.datanode.BlockSender.<init>(BlockSender.java:283)
    at org.apache.hadoop.hdfs.server.datanode.DataXceiver.readBlock(DataXceiver.java:537)
    at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opReadBlock(Receiver.java:148)
    at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:103)
    at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:246)
    at java.lang.Thread.run(Thread.java:744)


如果我检查堆栈顶部的源代码行449是此方法的一部分,并且始终位于突出显示的右花括号中。每次发生此问题时,堆栈跟踪都是相同的,而我在Java 7和Java 8上已经看到过。

public E get(Object obj, Comparator<?> cmp) {
    Objects.requireNonNull(obj);

    Node<E> node = root;
    while (node != null) {
      E[] entries = node.entries;

      int leftIndex = node.leftIndex;
      int result = compare(obj, entries[leftIndex], cmp);
      if (result < 0) {
        node = node.left;
      } else if (result == 0) {
        return entries[leftIndex];
      } else {
        int rightIndex = node.rightIndex;
        if (leftIndex != rightIndex) {
          result = compare(obj, entries[rightIndex], cmp);
        }
        if (result == 0) {
          return entries[rightIndex];
        } else if (result > 0) {
          node = node.right;
        } else {
          int low = leftIndex + 1;
          int high = rightIndex - 1;
          while (low <= high) {
            int mid = (low + high) >>> 1;
            result = compare(obj, entries[mid], cmp);
            if (result > 0) {
              low = mid + 1;
            } else if (result < 0) {
              high = mid - 1;
            } else {
              return entries[mid];
            }
          }
          return null;
        }
      }
    } // *** This is line 449 which the jstack always has at the top of the stack.
    return null;
  }


我有同一行的其他jstack示例,其中行号看起来正确,因此,我认为我看的不是该类的错误版本。肯定已使用与运行进程的同一用户相同的Java主页中的jstack命令捕获了jstack。关于样本的其他所有内容看起来都是正确的。

任何人都可以提供任何原因说明为什么jstack总是将右括号显示为可运行行吗?在查看许多jstacks输出之前,我从未见过。

更新

调查这是由编译和源代码中的不匹配引起的建议,我从与上述相同的过程中找到了另一个堆栈样本:

"Thread-41" daemon prio=10 tid=0x0000000003c39000 nid=0x1c6fe1 runnable [0x00007f1a4b7b8000]
   java.lang.Thread.State: RUNNABLE
    at org.apache.hadoop.hdfs.util.FoldedTreeSet.removeAndGet(FoldedTreeSet.java:879)
    at org.apache.hadoop.hdfs.util.FoldedTreeSet.removeAndGet(FoldedTreeSet.java:892)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.ReplicaMap.remove(ReplicaMap.java:162)
    - locked <0x0000000751682590> (a org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl)
    at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.invalidate(FsDatasetImpl.java:2021)
    - locked <0x0000000751682590> (a org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl)
    at org.apache.hadoop.hdfs.server.datanode.BPOfferService.processCommandFromActive(BPOfferService.java:686)
    at org.apache.hadoop.hdfs.server.datanode.BPOfferService.processCommandFromActor(BPOfferService.java:632)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.processCommand(BPServiceActor.java:729)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.offerService(BPServiceActor.java:539)
    at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:695)
    at java.lang.Thread.run(Thread.java:744)


这是同一类中的不同方法,但是removeAndGet方法中的代码与get中的代码非常相似。以下是相关的代码段:

  public E removeAndGet(Object obj) {
    return removeAndGet(obj, comparator); // *** This is 892, this is correct as per the stack trace above
  }


  public E removeAndGet(Object obj, Comparator<?> cmp) {
    Objects.requireNonNull(obj);

    if (!isEmpty()) {
      Node<E> node = root;
      while (node != null) {
        E[] entries = node.entries;
        int leftIndex = node.leftIndex;
        int result = compare(obj, entries[leftIndex], cmp);
        if (result < 0) {
          node = node.left;
        } else if (result == 0) {
          return removeElementLeft(node);
        } else {
          int rightIndex = node.rightIndex;
          if (leftIndex != rightIndex) {
            result = compare(obj, entries[rightIndex], cmp);
          }
          if (result == 0) {
            return removeElementRight(node);
          } else if (result > 0) {
            node = node.right;
          } else {
            int low = leftIndex + 1, high = rightIndex - 1;
            while (low <= high) {
              int mid = (low + high) >>> 1;
              result = compare(obj, entries[mid], cmp);
              if (result > 0) {
                low = mid + 1;
              } else if (result == 0) {
                return removeElementAt(node, mid);
              } else {
                high = mid - 1;
              }
            }
            return null;
          }
        }
      } // **** This is 879 - again the same as the get method
    }
    return null;
  }


源文件中稍后的代码似乎正确,但这奇怪地再次指向大括号。

最佳答案

在您的源代码和编译的类不同的情况下,有99%会发生这种情况。即编译的类是从其他来源(较新或较旧的版本)编译的。可能需要反编译您的类(从.class生成.java),看看是否有帮助

关于java - Java jstack示例指向右括号而不是代码行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59823880/

10-10 01:57