Java - 如何使我的应用程序长期运行稳定,以便它不会打嗝,冻结?

时间:2012-03-23 09:10:18

标签: java linux memory jvm ram

我的Java骨架如下所示。

当我在系统启动后运行几个小时后,它运行得很好。由于它运行了24小时,持续1天,我的应用程序或JVM本身出现了问题,例如打嗝/冻结问题,出版时没有任何事情发生,如he is dead

它发生了好几次,我的猜测是内存问题,当它运行很长时间,JVM某处导致它,但不是我的应用程序本身,因为前几个小时它没有停机时间。只有长达8小时才能开始。

示例:

public class Boot {

  public static void main(String[] args) {
       String myCmd = "java -cp /var/tmp/dist/App.jar main.main";
       Runtime.getRuntime().exec(myCmd);
       SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            createAndShowGUI();
          }
        });
  }

  private static void createAndShowGUI() {

    new Thread(new Runnable() {
      public void run() {
        //Server port listener
      }
    }).start();

    .....

    window = new JWindow();

    window.add("North", panelBgImg);
    window.pack();
    window.setLayout(new BorderLayout());
    window.setSize(screen.width, screen.height + 1);
    window.setLocationRelativeTo(null);
    window.setAlwaysOnTop(true);
    window.setVisible(true);        
  }
}

如何确保JVM不会导致我的应用程序被冻结,无论如何都要进行单元测试?这有助于长期解决这个问题吗?

例如:System.gc()和Runtime.gc()

2 个答案:

答案 0 :(得分:4)

如果您的应用程序冻结,原因更可能是某种死锁而不是内存不足错误。在后一种情况下,JVM会因异常而死亡。所以我的赌注是调用GC对你没有帮助。

这样的错误很难准确捕捉,因为它们很难可靠地重现。你有两个选择:

  • 将调试日志打印输出插入到您的代码中以获得有关正在发生的事情的更多线索,然后分析在应用程序冻结之前/期间生成的日志
  • 当你的应用程序被冻结时,停止JVM(使用kill命令或在Linux上的控制台上按Ctrl + \,在Windows上按Ctrl + Break) - 它将显示线程转储信息,列出所有正在运行和死锁的线程
  • 运行附带VisualVM的应用程序以查看内存使用模式

答案 1 :(得分:3)

对垃圾收集器的显式调用不能解决这样的问题。一般来说,你不使用它们。唯一可能的例外是当你知道你释放了大量内存并希望在下一个大任务进入之前清理它(但即便这样也不会发生)。

找到所发生情况的最佳方法是运行visualvm(带有默认的jdk,在bin / dir中)。连接到您的应用程序并开始查看其内存和CPU使用情况。如果这让你怀疑内存是问题,你可以拍摄快照并进行分析。