当前位置: 首页 > 面试题库 >

生成Java线程转储而不重新启动。

翟宏放
2023-03-14
问题内容

我想创建一个跟踪内存使用情况和cpu使用情况的线程。

如果应用程序达到较高级别,我想生成一个堆转储或线程转储。

有没有一种方法可以生成线程转储运行时而无需重新启动?


问题答案:

这是我们以编程方式进行的操作:http :
//pastebin.com/uS5jYpd4

我们使用JMX
ThreadMXBeanThreadInfo类:

ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0);
...

您也可以kill -QUIT pid在〜unix下进行操作以将堆栈转储到标准输出中。还有jstack来转储JVM的堆栈。

我们还具有一个自动化功能,如果应用程序的平均负载高于某个阈值,则该功能将转储堆栈:

private long lastCpuTimeMillis;
private long lastPollTimeMillis;

public void checkLoadAverage() {
    long now = System.currentTimeMillis();
    long currentCpuMillis = getTotalCpuTimeMillis();
    double loadAvg = calcLoadAveragePercentage(now, currentCpuMillis);
    if (loadAvg > LOAD_AVERAGE_DUMP_THRESHOLD) {
        try {
            dumpStack("Load average percentage is " + loadAvg);
        } catch (IOException e) {
            // Oh well, we tried
        }
    }
    lastCpuTimeMillis = currentCpuMillis;
    lastPollTimeMillis = now;
}

private long getTotalCpuTimeMillis() {
    long total = 0;
    for (long id : threadMxBean.getAllThreadIds()) {
        long cpuTime = threadMxBean.getThreadCpuTime(id);
        if (cpuTime > 0) {
            total += cpuTime;
        }
    }
    // since is in nano-seconds
    long currentCpuMillis = total / 1000000;
    return currentCpuMillis;
}

private double calcLoadAveragePercentage(long now, long currentCpuMillis) {
    long timeDiff = now - lastPollTimeMillis;
    if (timeDiff == 0) {
        timeDiff = 1;
    }
    long cpuDiff = currentCpuMillis - lastCpuTimeMillis;
    double loadAvg = (double) cpuDiff / (double) timeDiff;
    return loadAvg;
}


 类似资料:
  • 问题内容: 除了堆转储(java_pid14941.hprof),Java 6还会生成线程转储吗? 这就是我的一个应用程序发生的事情。 java.lang.OutOfMemoryError:超出了GC开销限制将堆倾倒到java_pid14941.hprof … 我确实在工作目录中找到了ava_pid14941.hprof,但没有找到任何包含线程转储的文件。当我收到此OutOfMemory错误时,我

  • 问题内容: 我有一个最终应该生成的程序。程序代码为: 我使用以下参数运行程序: 该程序因OutOfMemory失败,但未生成转储文件。 你知道为什么吗? 问题答案: 对于初学者,请删除XX选项以及 之前的 所有选项,否则,请将参数传递给Java程序而不是JVM

  • 问题内容: 我试图编写一个文件监视器,它将检查文件是否添加了新行,该监视器实际上是一个线程,它将始终由randomaccessfile读取该行。 这是监视器的核心代码: 这是一些帮助类: 这是调用监视器的示例: 现在,我的问题是,如果我仅调用以下代码,代码就可以很好地工作: 这将监视文件的行追加,并通知侦听器。 但是,当我致电: 这意味着我想监视另一个文件而不是之前。 因此,在Monitor中,我

  • 问题内容: 我正在尝试为我的Java游戏添加重启/重播功能。当前在我的Game类(GUI和游戏被初始化的地方)中,我有: 游戏对象包含整个游戏窗口的GUI,并包含各种对象(例如实际游戏窗口,计分板,倒数计时器等)。 我想添加一个功能,如果他们单击GUI上的重新启动按钮或游戏结束后,游戏将重新启动(以及倒计时和计分)。我确实意识到最好重新实例化对象(计分,倒数),但是一旦实例化,它们便成为我的GUI

  • 问题内容: 问题场景:在sonic MF容器(jvm)中发现了问题。该容器托管了一些负责db操作和消息转换的Java服务。启动后,该容器可以正常运行2-3周,并自行终止而不抛出任何例外。 经过大量研究,我们无法找出导致jvm(MF容器)关闭的原因或原因。 有没有一种方法可以在jvm自动关闭时获取线程转储?我正在使用Java 1.6。我应该采取其他方法解决此问题吗? 提前致谢。 问题答案: 您可以尝

  • 问题内容: 我很难找到一种方法来启动,停止和重新启动Java中的线程。 具体来说,我在中有一个类Task(当前实现)。我的主应用程序需要能够在线程上启动此任务,在需要时停止(杀死)该线程,有时还可以杀死并重新启动该线程… 我的第一次尝试是与,但我似乎找不到办法重新启动任务。当我使用任何将来的呼叫失败时,因为是“关机” … 那么,我该怎么做呢? 问题答案: 一旦线程停止,你将无法重新启动它。但是,没