Сокращение объема памяти нескольких процессов Java в Solaris (UNIX) - PullRequest
1 голос
/ 11 февраля 2011

Есть ли способ заставить процесс Java либо разветвляться, либо запускать другой процесс Java и использовать разделяемую память, чтобы минимизировать использование ОЗУ?

Будет много процессов, чтобы можно было безопасно убить одного, не затрагивая других. Также это позволит просто определить, какие потоки используют больше памяти или ЦП, если они находятся в отдельных процессах. Это должно позволить любому процессу иметь сбой или OutOfMemoryError, не затрагивая другие процессы.

Было бы неплохо, если бы у нас было 100-300 Java-процессов, запущенных одновременно, каждый со своей целью. Я понимаю, что нам, возможно, придется ограничить это число и потребовать, чтобы процессы выполняли несколько ролей, если мы не хотим отнимать слишком много памяти из базы данных и файловой системы.

Edit:
Я думаю, что я неправильно понял значение, когда сказал «Общая память». Я имею в виду только память, которую можно использовать среди нескольких процессов, таких как классы Java (не переменные). Все java-пакеты и библиотеки можно использовать повторно, если это возможно.

Ответы [ 3 ]

0 голосов
/ 11 февраля 2011

Нет, насколько я могу судить, это невозможно.Для этого есть несколько причин:

  1. Владение общими объектами было бы сомнительным делом, поэтому ограничение памяти для каждого потока было бы неосуществимым.
  2. Если поток умирает, этосерьезные проблемы.Потоки не умирают неожиданно просто так, если вы не устанавливаете обработчик исключений для всех целей.Единственная причина, по которой потоки непреднамеренно умирают в хорошо написанной системе, заключается в том, что выбрасывается Error, а это означает, что система нестабильна, и, как правило, также означает, что виртуальная машина должна быть остановлена ​​как можно быстрее.За исключением некоторых особых случаев (в частности, приложений / веб-серверов) Маловероятно, что любая система сможет продолжить работу после потери одного из потоков.Чаще всего это может иметь страшные последствия.

Обновление: Обнаружив, что это веб-сервер, для которого необходимо решение, я постараюсь пойти немного дальше,Хотя Java не была разработана для такого уровня изоляции, как вам нужно.некоторые функции могут быть реализованы агентом JVMTI .В частности, потоки могут быть остановлены , объекты, достижимые потоком, могут проверяться , запрашивать время, использованное каждым потоком и так далее.Плохая новость заключается в том, что ваш агент должен быть написан на C или чем-то подобном, его сложно отладить, и любые ошибки могут привести к сбою виртуальной машины.

0 голосов
/ 24 февраля 2011

@ Джордж Бейли - Только что уловил ваш комментарий выше.

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

Вы можете прочитать больше здесь:

http://download.oracle.com/javase/1.5.0/docs/guide/vm/class-data-sharing.html

Возможно, вы захотите проявить агрессивность в отношении параметров изменения размера кучи, чтобы уменьшить занимаемую площадь. Хотя и полукоммерческий, я поддерживаю небольшой программный пакет, который управляет рабочими нагрузками для нескольких (сотен) JVM и динамически управляет вводом-выводом на уровне ОС и приоритетом процесса для достижения целей рабочей нагрузки. WLM бедняка для JVM. Таким образом, мне не удалось управлять эргономикой JVM во время выполнения, но подход WLM работает на удивление хорошо. Дайте мне знать, если вы хотите больше информации.

0 голосов
/ 11 февраля 2011

Что вы подразумеваете под общей памятью? Вы говорите о памяти хост-системы?

Поскольку вы используете Solaris, потоки Java являются потоками Solaris, и каждый поток получает свой собственный процесс. Но Java по-прежнему работает с параметрами памяти JVM, которые вы ей задаете. Если вы получаете OutOfMemoryError, пул памяти JVM достиг своего предела, а не хост-системы. Другими словами, в Java вы никогда не обращаетесь к разделяемой памяти - это работа JVM. Если вашим процессам Java требуется больше памяти, вы должны увеличить лимит памяти JVM. Но вся эта память управляется JVM. Чтобы действительно получить доступ к разделяемой памяти, вам нужно использовать JNI для выхода из JVM и в память хоста.

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

...