我正在开发非常庞大的基于Java web的应用程序。由于在开发过程中没有进行适当的日志记录,因此我很难设置断点并调试应用程序,因为我不知道执行顺序。在执行某些操作后,是否有任何机制可以获取正在运行的java应用程序的完整Call Stack。
我在网上搜索了很长时间,但无法找到具体的解决方案。如果有什么东西请建议我。感谢
答案 0 :(得分:18)
方法1:从命令行使用jstack实用程序(JDK发行版的一部分)。
方法2:将信号3发送到java进程,它将在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()
。
答案 1 :(得分:6)
Thread.dumpStack()
将当前线程的堆栈跟踪打印到标准错误流。
Thread.getAllStackTraces()
返回所有活动线程的堆栈跟踪映射。
Thread.getStackTrace()
返回表示此线程的堆栈转储的堆栈跟踪元素数组。
答案 2 :(得分:5)
看看Throwable.getStackTrace()
。只需创建一个新的Throwable
;你实际上不需要throw
它。
答案 3 :(得分:3)
您可以通过按 Ctrl + Break 或发送信号3(在基于Unix的系统上)来触发堆栈转储。请注意,您将获得每个线程的堆栈跟踪。这将转到标准错误,因此请确保您的日志记录正在捕获此内容。
您可以通过
以编程方式执行此操作Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
这里有关于获取和分析堆栈跟踪的more info。
正如您所指出的,BTrace是另一种可能性。这是使用它的an SO answer。
答案 4 :(得分:0)
有一些选择:
为您的代码添加一些基本日志记录:
new RuntimeException().printStackTrace();
这会使静态跟踪到stderr
答案 5 :(得分:0)
为什么不使用像AspectJ这样的AOP工具来捕获这些值并记录?您可以使用execution()切点和after()建议。对于非生产部署,您可以记录所有方法调用以及传递的值和返回值。对于生产环境来说,这将是太多的开销。为此,您可以在局部变量中存储传递的值(在AspectJ建议中获得的对象args []),并且只在异常情况下记录它。但即使在这种情况下也会有一些性能损失,因为原始值将被装箱以作为Object []传递给您的建议。