Почему система. Похоже, что gc () не влияет на некоторые JVM - PullRequest
3 голосов
/ 08 июля 2010

Я разрабатывал небольшую утилиту Java, которая использует две платформы: Encog и Jetty для обеспечения функциональности нейронной сети для веб-сайта.

Код «закончен» в том смысле, что он делает все, что ему нужно, но у меня есть некоторые проблемы с использованием памяти. При работе на моей машине для разработки использование памяти колеблется между 4 МБ и 13 МБ, когда приложение выполняет какие-то задачи (обучение нейронных сетей), и самое большее оно использует около 18 МБ. Это очень хорошее использование, и я думаю, что это связано с тем, что я вызываю System.GC () довольно регулярно. Я делаю это, потому что время обработки не имеет значения для меня, но использование памяти имеет значение.

Так что все это прекрасно работает на моей машине, но как только я включаю его в сеть на нашем сервере (общий хостинг Unix с ограничением памяти), он начинает использовать около 19 МБ и увеличивает объем используемой памяти до сотен МБ. , Это те же самые вещи, которые я делал на тестировании. Я полагаю, что единственный способ уменьшить использование памяти - это выйти из приложения и перезапустить его.

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

Я рассмотрел использование GCJ для компиляции приложения, но я не знаю, стоит ли уделять этому много времени и поможет ли это на самом деле.

Спасибо за помощь!

  • ОБНОВЛЕНИЕ: Разработка на Mac OS 10.6.3 и сервере на Unix OS, но я не знаю что. (Сервер из WebFaction)

Ответы [ 5 ]

7 голосов
/ 08 июля 2010

Я думаю, это связано с тем, что я довольно регулярно вызываю System.GC ()

Вы не должны этого делать, это почти никогда не полезно.

Сборщик мусора работает наиболее эффективно, когда у него много памяти, поэтому он будет использовать большую часть того, что может получить.Я думаю, все, что вам нужно сделать, это установить максимальный размер кучи в 32 МБ с параметром командной строки -Xmx32m - значение по умолчанию зависит от того, считает ли JVM, что оно работает в системе «серверного класса», и в этом случае предполагаетсячто вы хотите, чтобы приложение использовало как можно больше памяти, чтобы повысить пропускную способность.

Кстати, если вы работаете на 64-битной JVM на сервере, ему на законных основаниях потребуется больше памяти (обычнопримерно на 30%), чем на 32-битной JVM из-за больших ссылок.

1 голос
/ 08 июля 2010

Две точки, которые вы могли бы рассмотреть:

  • Вызовы System.gc могут быть отключены параметром командной строки (-XX: -DisableExplicitGC), я думаю, что поведение также зависит от алгоритма gc vmиспользует.Обычно вызов gc следует оставить для jvm
  • До тех пор, пока для jvm достаточно памяти, я не вижу ничего плохого в использовании этой памяти для увеличения производительности приложений и gc.Как сказал Michael Borgwardt, вы можете ограничить объем памяти, используемый vm в командной строке.
0 голосов
/ 03 августа 2010

Возможно, сервер использует больше памяти, поскольку нагрузка на ваше приложение выше, и поэтому используется больше потоков? Jetty будет использовать несколько потоков для распределения нагрузки при большом количестве запросов. Стоит взглянуть на количество потоков на сервере по сравнению с тестовой машиной.

0 голосов
/ 08 июля 2010

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

Таким образом, если у вас есть много объектов, которые используются, а затем выбрасываются, вы медленно и надежно заполните доступную память. Затем вы можете запросить на сборку мусора, но это всего лишь подсказка, и JVM может предпочесть не слушать.

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

Существует ли преднамеренное требование низкого использования памяти? Если нет, просто дайте ему поработать и посмотрите, как ведет себя JVM. Используйте jvisualvm для подключения и мониторинга.

0 голосов
/ 08 июля 2010

Также вы можете посмотреть, в каком режиме была запущена JVM при развертывании в сети.Я думаю, это серверная виртуальная машина.Взгляните на различия между двумя прямо здесь, на stackoverflow.Также посмотрите, какой сборщик мусора на самом деле работает в реальном развертывании.Посмотрите, можете ли вы настроить поведение GC или изменить алгоритм GC. См. Параметры -X, если это JVM Sun.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...