2015-03-14 2 views
3

Я запускал 3 приложения Java, каждый в своей собственной JVM.Как программы Java в разных JVM-системах могут непреднамеренно влиять друг на друга?

Затем все приложения застыли (в то же время) примерно через 30 минут. При работе только с одной JVM проблема не возникает, и она оказалась стабильной более 13 часов при большой нагрузке. Проблема возникает только при запуске нескольких JVM.

Чтобы уточнить, между программами не существует (предполагаемого) взаимодействия. Кроме того, программы используют 2 потока, каждый из которых работает вместе синхронно. Приложения идентичны, просто работают на разных данных. Опять же, они должны быть полностью независимы друг от друга, поскольку каждая программа работает на собственной JVM.

Я не прошу конкретного решения моей проблемы, но мне интересно узнать, является ли обычное поведение обычным или нет.

И самое главное, если это хорошо известная проблема, существуют ли какие-либо правила большого пальца о том, как избежать таких проблем? Существуют ли аспекты многопоточности (в моем случае каждая программа использует два потока), которые, как известно, вызывают подобные проблемы?

+ Обновление: Прежде всего, вот код, который используется для операций ожидания/уведомления между потоками.

Основная нить, только два метода (называемые в цикле):

public void waitCycles(int c) { 
    worker.setWaitDuration(c); 
    try { 
     synchronized (this) { 
      this.wait(500);//very unlikely to actually wait 500ms. Should be notified. 
     } 
    } 
    catch (Exception e) { 
    } 
} 
float[] learn(boolean[] values) { 
    worker.setLearnValues(values); 
    try { 
     synchronized (this) { 
      this.wait(500);//Same as above 
     } 
    } 
    catch (Exception e) { 
    } 
    float[] out = worker.quality; 
    worker.quality = null; 
    return out; 
} 

А вот код из Рабоче-Class (расширяет тему), а также часть цикла:

 if (learnValues != null) { 
      float[] q = new float[learnValues.length]; 
      for (int i = 0; i < learnValues.length; i++) { 
       q[i] = outs[i].learn(learnValues[i], 1); 
      } 
      quality = q; 
      learnValues = null; 
      synchronized (host) { 
       host.notifyAll(); 
      } 
     } 
     //"waiter" is an integer value that is set by calling "setWaitDuration(int c)" 
     if (waiter > 0) { 
      waiter--; 
      if (waiter <= 0) { 
       waiter = -1; 
       synchronized (host) { 
        host.notifyAll(); 
       } 
      } 
     } 

После замораживания обеих потоков все еще потребляется много процессорного времени, что не имеет смысла, поскольку программы должны писать текстовые файлы, содержащие информацию о текущем ходе обучения, но этого не происходит (несмотря на то, что оба потока все еще работают). Я дважды проверял, нет бесконечных циклов while, которые могут вызвать это. И все еще не имеет смысла, почему все три программы замерзают, казалось бы, в одно и то же время. Я использую JDK8u25 и его встроенную JRE в Windows 8. У меня не было проблем с памятью.

+0

Как они синхронизируются и что делают программы? –

+0

Это программа машинного обучения, точнее искусственная нейронная сеть. Один поток оценивает качество ANN и отправляет ему учебные шаблоны, он также предоставляет несколько инструментов для анализа ANN. Второй поток содержит фактический ANN и выполняет все ANN-конкретные вычисления. Обеим потокам требуется как можно больше процессорного времени. Синхронизация выполняется в случае, если какой-либо поток выполняет действие, которое требует, чтобы другой поток ожидал. В конце спящий поток снова проснулся. Я использую в основном Thread.wait (время) и someMonitor.notifyAll() – Tonnz

+0

Каково состояние системы, когда три JVM зависают? Они вообще используют процессор? Или они все заблокированы? Есть ли другие потоки в JVM, способные добиться прогресса? Кроме того, какие версии ОС и Java? Это не известная проблема, поэтому в вашей системе может быть что-то не так. –

ответ

2

Две вещи сразу прийти в голову:

память
  1. Server. Запустив одновременно 3 JVM, ваш сервер может быть перегружен, и все 3 приложения значительно ухудшаются.

  2. Внешние IO, такие как диск/сеть. Если все ваши приложения зависят от дискового или сетевого подключения, а на вашем сервере закончилось дисковое пространство или произойдет сбой в сети, то у всех 3 могут быть проблемы одновременно

+0

Благодарим вас за ответ. Но, к сожалению, ни одна из этих вещей не может быть причиной моей проблемы. Знаете ли вы, и насколько тяжелая нагрузка может повлиять на ожидаемое время ожидания в Java? Единственное возможное объяснение, которое приходит мне на ум, заключается в том, что ожидающие потоки никогда не пробуждаются снова, но они должны просыпаться по прошествии определенного времени. Но если бы это было так, я бы заметил, что программы, по крайней мере, работают (даже если они работают очень медленно), но это не так. Я не вижу ничего в своем коде, который бы блокировал поток навсегда. – Tonnz

+0

Я должен заменить память - вы уверены, что она не находится где-то ближе к ФИЗИЧЕСКОЙ памяти компьютера (без обмена)? Несколько JVM не очень хорошо работают, когда у вас заканчивается память, они заставляют друг друга заменять и в конечном итоге блокировать весь компьютер ... Я видел это много раз. чтобы проверить его, вы можете попытаться отключить все пространство подкачки и использовать трекер памяти (диспетчер процессов в окнах), чтобы убедиться, что вы не используете больше 3/4 вашего бара. –

Смежные вопросы