17

我正在开发非常庞大的基于 Java Web 的应用程序。由于在开发过程中没有进行适当的日志记录,因此我很难设置断点并调试应用程序,因为我不知道执行顺序。执行某些操作后,是否有任何机制可以获取正在运行的 java 应用程序的完整调用堆栈。

我在网上搜索了很长时间,但无法得出具体的解决方案。如果有什么适合的,请建议我。谢谢

4

7 回答 7

23

方法 1:从命令行(JDK 发行版的一部分)使用 jstack 实用程序。

方法 2:向 java 进程发送信号 3,它将在 stdout 上转储堆栈跟踪。

方法 3:从应用程序内部调用 Thread.getAllStackTraces():

public class StackTraceDumper
{
    public static dumpAllStackTraces ()
    {
        for (Map.Entry <Thread, StackTraceElement []> entry: 
            Thread.getAllStackTraces().entrySet ())
        {
            System.out.println (entry.getKey ().getName () + ":");
            for (StackTraceElement element: entry.getValue ())
                System.out.println ("\t" + element);
        }
    }
}

然后StackTraceDumper.dumpAllStackTraces()在需要转储堆栈跟踪的地方使用。

于 2013-02-05T10:44:44.843 回答
6

Thread.dumpStack() 将当前线程的堆栈跟踪打印到标准错误流。 Thread.getAllStackTraces() 返回所有活动线程的堆栈跟踪映射。 Thread.getStackTrace() 返回表示此线程的堆栈转储的堆栈跟踪元素数组。

于 2013-02-05T10:38:44.500 回答
5

看看Throwable.getStackTrace()。只需创建一个新的Throwable;你实际上不必这样做throw

于 2013-02-05T10:37:09.787 回答
3

您可以通过按Ctrl+Break或发送信号 3(在基于 Unix 的系统上)触发堆栈转储。请注意,您将获得每个线程的堆栈跟踪。这将进入标准错误,因此请确保您的日志记录正在捕获它。

您可以通过编程方式执行此操作

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();

这是有关获取和分析堆栈跟踪的更多信息。

正如您所指出的,BTrace 是另一种可能性。这是一个关于使用它的答案。

于 2013-02-05T10:36:27.423 回答
0

为什么不使用像 AspectJ 这样的 AOP 工具来捕获这些值并记录下来?您可以将 execution() 切入点与 after() 建议一起使用。对于非生产部署,您可以记录所有方法调用以及传递的值和返回值。对于生产环境来说,这将是太多的开销。为此,您可以将传递的值(在 AspectJ 建议中获得的 Object args[] )存储在局部变量中,并且仅在出现异常时记录它。但即使在这种情况下,也会有一些性能损失,因为原始值将被装箱以作为 Object[] 传递给您的建议。

于 2013-08-16T14:35:28.550 回答
0

有一些选项:

  • 在调试器中运行它,并暂停所有线程,然后你可以检查它们
  • 使用 VisualVM 连接到正在运行的进程并触发线程转储。它随 JDK 一起提供。
  • 在命令行上使用 jstack 来转储线程。

在您的代码中添加一些基本的日志记录:

new RuntimeException().printStackTrace();

这会将静态跟踪发送到 stderr

于 2013-02-05T10:41:58.807 回答
0

以防万一人们正在阅读这篇文章以了解如何获取当前线程堆栈的一个或多个类:

StackTraceElement[] stack = Thread.currentThread().getStackTrace();
String smallStack = "Calling classes: " + System.lineSeparator() + stack[2] + System.lineSeparator() + stack[3];

这将获取当前线程的堆栈。

  • stack[0]将是 getStackTrace 调用本身。
  • stack[1]将是您正在工作的代码行。
  • 第一个“有趣”的堆栈元素也是stack[2]如此。stack[3]
于 2021-09-10T07:13:56.810 回答