Уменьшение объема памяти нескольких процессов Java в Solaris (UNIX)

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

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

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

Правка:
Мне кажется, я уловил неверный смысл, когда сказал "общая память". Я имею в виду просто память, которая может использоваться несколькими процессами, такими как классы Java (а не переменные). Все пакеты и библиотеки Java можно использовать повторно, если это возможно.


person 700 Software    schedule 10.02.2011    source источник
comment
download.oracle.com/javase/ 1.5.0/docs/guide/vm/   -  person Jé Queue    schedule 11.02.2011
comment
Спасибо, кажется, это то, что я ищу. Пожалуйста, перейдите к ответу, чтобы я мог принять. @Xepoch   -  person 700 Software    schedule 24.02.2011


Ответы (3)


@George Baily - только что заметил ваш комментарий выше.

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

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

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

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

person Jé Queue    schedule 24.02.2011
comment
Следуя документу, он сгенерировал общий архив (classes.jsa) с помощью -Xshare:dump на сервере JVM. - person ernesto; 03.08.2012

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

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

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

person Snapman    schedule 10.02.2011
comment
Это тот случай, когда одна JVM запускает другую. Я имею в виду ядро ​​Java или что-либо, что остается неизменным среди родительского и дочернего процессов или изначально одинаково, но позже некоторые сегменты могут быть скопированы для обработки определенного пространства, если их нужно изменить. Я не знаю, о чем говорю. Я просто хочу попытаться максимально сократить использование оперативной памяти. Я знаю, что мне придется заблокировать -Xmx, чтобы все было разумно. Однако хранилище классов (не переменных) для таких вещей, как соединитель MySQL, все пакеты Java; Java-почта, генератор PDF. Они часто будут использоваться среди нескольких процессов. - person 700 Software; 11.02.2011

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

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

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

person biziclop    schedule 10.02.2011
comment
Это для сервера веб-приложений. Некоторые веб-приложения будут часто изменяться в производственной среде. Таким образом, неизбежно будут бесконечные циклы и переполнения памяти, вызванные ошибочным кодом. Если это произойдет, его придется изолировать от остальных потоков — я ожидаю, что это может быть полностью достигнуто только путем разделения процессов. При необходимости существующие потоки в процессе с бесконечным циклом могут завершиться, и веб-сервер может знать, что он не должен запускать (запрашивать) какие-либо новые потоки в этом процессе. Не смейтесь надо мной за то, что я пишу новый веб-сервер. Это было очень хорошо продумано. - person 700 Software; 11.02.2011
comment
@George Bailey Почему я должен смеяться? Вместо этого я обновлю свой ответ. - person biziclop; 11.02.2011