Как убедиться, что JVM начинается со значения Xms - PullRequest
3 голосов
/ 14 мая 2009

Когда я запускаю Java-программу с начальным размером кучи 3G (установленным аргументом -Xms3072m VM), JVM не запускается с этим размером. Это начинается с 400 м или около того, а затем продолжает приобретать больше памяти по мере необходимости.

Это серьезная проблема для меня. Я знаю, что JVM понадобится указанное количество через некоторое время. И когда JVM увеличивается, его память соответствует потребности, она замедляется. В то время, когда JVM приобретает больше памяти, значительное количество времени уходит на сборку мусора. И я полагаю, приобретение памяти - дорогостоящая задача.

Как мне убедиться, что JVM действительно учитывает параметр размера стартовой кучи?

Обновление: Это приложение создает множество объектов, большинство из которых быстро умирает. Некоторые результирующие объекты должны оставаться в памяти (которые переносятся из молодой кучи). Во время этой операции все эти объекты должны находиться в памяти. После операции я вижу, что все объекты в молодой куче заявлены успешно. Таким образом, нет утечек памяти.

Та же операция выполняется плавно, когда размер кучи достигает 3G. Это ясно указывает на то, что на приобретение памяти затрачивается дополнительное время.

Это Солнце JDK 5.

Ответы [ 4 ]

3 голосов
/ 27 мая 2009

Если я не ошибаюсь, Java пытается получить резервирование памяти из ОС. Таким образом, если вы запрашиваете 3 ГБ в качестве Xms, Java спросит у ОС, если она доступна, но не запускается сразу со всей памятью ... она может даже зарезервировать ее (не выделять). Но это детали.

Обычно JVM запускается до размера Xms, прежде чем он начинает серьезную сборку мусора старого поколения. Молодое поколение GC работает все время. Обычно GC заметен только тогда, когда работает GC старого поколения, а виртуальная машина находится между Xms и Xmx или, если вы установите его на то же значение, примерно равна Xmx.

Если вам нужно много памяти для недолговечных объектов, увеличьте эту область памяти, установив для молодой области значение ... скажем, 1 ГБ -XX: NewSize = 1g , поскольку его перемещение является дорогостоящим "мусор" из молодых "ведер" в старое поколение. Поскольку в случае, если он еще не превратился в настоящий мусор, JVM проверяет мусор, не находит его, копирует его между оставшимися в живых пространствами и, наконец, перемещается в старый ген. Поэтому попытайтесь подавить проверку на наличие мусора в молодом поколении, когда вы знаете, что у вас его нет, и как-то откладываете это ...

Попробуйте!

2 голосов
/ 14 мая 2009

Я считаю, что ваша проблема не в том, откуда вы думаете.

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

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

Моя догадка - создание и удаление объектов и циклы GC.

В любом случае, -Xms должен устанавливать минимальный размер кучи ( проверьте это с вашей JVM , если это не Sun). Еще раз проверьте, почему вы думаете, что это не так.

0 голосов
/ 14 мая 2009

Почему вы думаете, что распределение кучи не правильно? Использование любого инструмента операционной системы, показывающего только 400 м, не означает, что оно не выделено.

Я не совсем понимаю, что вы ищете. 400м и выше уже проблема, или ваша программа должна так сильно нуждаться? Если вам действительно нужно иметь дело с таким большим количеством памяти, и вам кажется, что вам нужно много объектов, вы можете сделать несколько вещей:

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

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

Упомянутые вами характеристики будут сценарием, в котором создается много объектов, и вскоре после этого они снова удаляются. В противном случае сборка мусора не будет проблемой (своего рода поколения GC). Это означает, что у вас есть только «молодые» объекты. Рассмотрите возможность использования пула объектов, если вам нужны объекты только в течение короткого периода времени. Это вообще исключило бы сборку мусора.

Если вы знаете, что в вашем коде хорошие времена для запуска gc, вы можете запустить его вручную, чтобы увидеть, если он что-то изменит. Это то, что вам нужно

  Runtime r = Runtime.getRuntime();
  r.gc();

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

0 голосов
/ 14 мая 2009

Я использовал vm от Sun и начал с минимального набора в 14 гигабайт, и все началось с этого. Может быть, вы должны попробовать установить оба значения xms и xmx в одну и ту же amt, т.е. попробуйте это -Xms3072m -Xmx3072m

...