gpt4 book ai didi

Java jstack 示例指向右括号而不是代码行

转载 作者:行者123 更新时间:2023-12-01 18:46:38 25 4
gpt4 key购买 nike

我正在尝试调试 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 示例,其中行号看起来是正确的,因此我不认为我正在查看该类的错误版本。 jstack 肯定是由与正在运行的进程相同的用户使用 jstack 命令从同一 Java 主目录捕获的。有关样本的其他所有内容看起来都是正确的。

任何人都可以提供任何理由来解释为什么 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% 的情况都会发生这种情况。 IE。编译的类是从不同的源(较新或较旧的版本)编译的。尝试反编译你的类(从.class生成.java)看看是否有帮助

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

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