Java уменьшает использование памяти - PullRequest
3 голосов
/ 03 февраля 2012

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

Итак, вопрос в том, как заставить Java использовать меньше памяти?

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

PS мое приложениерегулярно обновляется на производственном сервере, и мне нужно отслеживать использование памяти на предмет утечек и т. д. (как правило, утечек нет, но если они появляются, я должен увидеть их как можно быстрее), а также мне нужно предсказать время, когда я должен обновитьмое оборудование.Все это очень сложно сделать, если jvm непредсказуемо изменит свой голод.Поэтому единственное, что я хочу, это заставить jvm быть предсказуемым в использовании памяти (если число пользователей удваивается, память тоже должна удваиваться)

Ответы [ 4 ]

7 голосов
/ 03 февраля 2012

Вы можете указать, чтобы он использовал меньше памяти, вызвав java с параметром -Xmx, то есть:

java -Xmx128M xxx

будет работать с максимальным объемом 128 МБ ( по умолчанию в Java 6 , для него установлено значение "Меньше 1/4 физической памяти или 1 ГБ" )

Не звоните System.gc() все время ... это ваше время, которое вы будете тратить; -)

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

4 голосов
/ 03 февраля 2012

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

Это зависит от того, что вы имеете в виду «больше памяти, чем нужно». Если вы имеете в виду, больше, чем минимальный объем памяти для представления объектов вашего приложения, то вы правы.

Это стандартное поведение, когда Java использует больше памяти, чем тот минимум, который теоретически может сойти с рук. «Что еще хуже», большинство JVM не возвращают память операционной системе ... даже если эта память была освобождена GC. Оба эти свойства необходимы для эффективной работы сборщика мусора общего назначения.

Если это неприемлемо для вас, вы не должны использовать язык для сбора мусора. Используйте C или C ++. (Но также имейте в виду, что для распределителей памяти C / C ++ необычно иметь возможность возвращать память операционной системе либо ... даже если реализация позволяет это.)


Положительной стороной этого является то, что Java (и фактически любой язык GC) на самом деле будет работать лучше, если вы выделите ему много памяти. Современные GC работают более эффективно, так как соотношение мусора и не мусора увеличивается, и большая куча делает это возможным. (Конечно, вы можете зайти слишком далеко, особенно если приложение конкурирует с другими вещами за реальную память.)


Как уже говорилось в других ответах, вызов System.gc() не помогает. Это вряд ли приведет к возвращению какой-либо памяти. Хуже того, вы, скорее всего, будете запускать GC, когда уровень мусора слишком низок для эффективной работы, поэтому вы будете увеличивать время ЦП без какой-либо выгоды.


Относительно вашего "PS":

  1. Я не думаю, что есть способ (надежно) обнаружить наличие утечки памяти ... кроме мониторинга тенденций использования памяти.

  2. Я не думаю, что есть способ (надежно) предсказать, когда у вас появится новое оборудование ... кроме трендов мониторинга использования памяти (и других).

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

С другой стороны, вы можете сказать то же самое о приложении C / C ++.

3 голосов
/ 03 февраля 2012

Во-первых, как поможет ваша БЕСПЛАТНАЯ память, если вы вызываете System.gc ()? И вызов System.gc () даже не является хорошим вариантом. Если вы хотите более агрессивный сборщик мусора, для этого есть правила. Вместо этого вы должны запустить его с меньшим объемом памяти с -Xmx

2 голосов
/ 03 февраля 2012

Нет, не в порядке. System.gc () не гарантирует, если / когда запустится сборщик мусора. Более того, System.gc () может вызывать сборщик мусора, что часто приводит к увеличению затрат времени на сборку мусора, чем запуск приложения.

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

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