【问题标题】:How to implement stack trace when there is a failure?发生故障时如何实现堆栈跟踪?
【发布时间】:2015-06-11 02:30:56
【问题描述】:

我最近接受了一次面试,并被要求设计/实现堆栈跟踪功能。这是我想出的。

  • 维护一个堆栈,其中包含从程序的主要入口点进行的所有方法调用。
  • 如果在执行过程中的任何时候出现错误,请暂停程序并通过弹出每个元素来打印整个堆栈。

然后我被问了两个问题:

  1. 如何/在哪里初始化此堆栈?
  2. 如果堆栈不运行 OOM,您将如何决定堆栈应存储多少数据?为什么 JVM 从来没有因为堆栈而运行 OOM?

对于我说的第一个问题,堆栈应该是静态的,应该在程序开始时进行初始化。但我不确定第二个问题。我试图阅读 JVM 是如何做到这一点的,但它有点复杂。我尝试用谷歌搜索基本实现,但找不到。如果有人能指出我应该寻找什么来回答这个问题的正确方向,我将不胜感激。

【问题讨论】:

  • Java default stack size 的可能重复项
  • 看看 Throwables printStackTrace()
  • 抱歉投票结束,但我意识到这两个问题并不相同。你可以通过这个问题找到很多关于堆栈分配的信息:stackoverflow.com/questions/20030120/java-default-stack-size
  • 如果您在某些时候需要堆栈跟踪,最简单的方法是在那里抛出并捕获异常并从异常中获取堆栈跟踪。
  • @user489041 我认为这不会为您提供 OP 正在寻找的信息。 printStackTrace() 只需使用 getStackTrace() 并对其进行格式化。

标签: java


【解决方案1】:

有点开放式的问题,这是我的看法:

  1. 堆栈不应是静态的 - 每个线程 有一个堆栈,而不是每个程序,并且可以在程序的生命周期内添加和删除线程。所以堆栈也必须动态分配。
  2. Java 堆栈可能溢出。这可能与OOM不同,但没有那么不同。至于在堆栈中存储什么 - 我会选择用户可配置的,因为在开发模式和生产模式下运行时要求非常不同。您还可以讨论可能的堆栈管理改进,例如tail-call optimizations。这些可以防止堆栈溢出,但会影响代码的编写方式。

无论如何,我的 2 美分。

【讨论】:

    【解决方案2】:

    我不会在任何地方存储任何堆栈跟踪信息,因为它已经存储在每个线程的堆栈帧中。当需要堆栈跟踪时(例如抛出异常),我会从堆栈框架构建它。

    问题是我不确定堆栈帧是否包含执行此操作所需的所有信息。

    【讨论】:

      【解决方案3】:

      调用 Thread.currentThread().getStackTrace() 以返回一个 StackElement[],它可以打印到您的日志中。

      【讨论】:

      • 我认为这不是 OP 所要求的
      猜你喜欢
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多