Java - Как я могу сделать свое приложение стабильным в течение длительного времени, чтобы оно не икало, не зависало?

Мой скелет 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()


person Community    schedule 23.03.2012    source источник


Ответы (2)


Если ваше приложение зависает, причина, скорее всего, в какой-то взаимоблокировке, а не в ошибке нехватки памяти. В последнем случае JVM просто умирает с исключением. Так что я держу пари, что вызов GC вам здесь не поможет.

Подобные ошибки трудно поймать именно потому, что их очень трудно надежно воспроизвести. Однако у вас есть несколько вариантов:

  • вставьте распечатки журнала отладки в свой код, чтобы получить больше информации о том, что происходит, а затем проанализируйте журналы, созданные до / во время зависания вашего приложения.
  • остановить JVM (с помощью команды kill или Ctrl+\ из консоли в Linux, Ctrl+Break в Windows), когда ваше приложение зависло — оно отобразит информацию о дампе потока, перечислив все запущенные и заблокированные потоки
  • запустите приложение с подключенной VisualVM, чтобы увидеть шаблоны использования памяти
person Péter Török    schedule 23.03.2012

Явные вызовы сборщика мусора не решают подобных проблем. В общем, вы их не используете. Единственное возможное исключение — это когда вы знаете, что освободили много памяти, и хотите очистить ее до того, как появится следующая большая задача (но даже это никогда не происходит).

Лучший способ узнать, что происходит, — запустить visualvm (поставляется с jdk по умолчанию в папке bin/dir). Подключитесь к своему приложению и начните смотреть на его использование памяти и процессора. Если это заставляет вас подозревать, что проблема связана с памятью, вы можете сделать снимки и проанализировать их.

person Thirler    schedule 23.03.2012