如何让一个正在运行的应用程序的Java调用栈(How to get Java Call Stack

2019-07-19 07:11发布

我的工作非常庞大的Java基于web的应用。 至于有没有做适当的记录,而发展所以其我很难把破发点并调试应用程序,因为我不知道的执行顺序。 是否有任何机制来获取正在运行的Java应用程序的完整调用堆栈后,我执行一些动作。

我搜索它的净长的时间,但不能来具体的解决方案。 如果事情是有它请给我建议。 谢谢

Answer 1:

方法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()你需要转储堆栈跟踪。



Answer 2:

Thread.dumpStack()打印当前线程的堆栈跟踪到标准错误流。 Thread.getAllStackTraces()返回所有活动线程地图的堆栈跟踪的。 Thread.getStackTrace()返回一个表示该线程堆栈转储的堆栈跟踪元件的阵列。



Answer 3:

看看Throwable.getStackTrace() 只要创建一个新Throwable ; 你实际上并不需要throw它。



Answer 4:

可以通过按下Ctrl +额 ,或发送信号3(在基于Unix的系统中)触发堆栈转储。 请注意,您会得到每个线程的堆栈跟踪。 这将大大标准错误 ,所以请确保您的日志捕获此。

您可以通过编程方式做到这一点

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

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

如您所知,BTrace是另一种可能性。 下面是一个SO回答上使用它。



Answer 5:

有一些选项:

  • 在调试器中运行,并暂停所有线程,那么你就可以对其进行检查
  • 使用VisualVM的连接到正在运行的进程,并引发一个线程转储。 它配备了JDK。
  • 使用jstack在命令行上,转储线程。

添加一些基本的日志到您的代码:

new RuntimeException().printStackTrace();

将普林静态跟踪到stderr



Answer 6:

你为什么不使用一些AOP的工具,像AspectJ的捕捉到这些价值观和日志? 您可以使用执行()点着后()建议削减一起。 对于非生产部署中,可以记录所有的方法与传递的值和返回值调用一起。 这将是生产ENV开销太大。 对于您可以只保存在本地变量传递的值(对象ARGS [你AspectJ中的建议得到]),只记录它在例外情况下。 但是,即使在这种情况下,会有一些性能损失为原始值将作为盒装你的忠告对象[]传递。



文章来源: How to get Java Call Stack of a running application