2009-05-14 2 views
3

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

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

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

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

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

Это Sun JDK 5.

+1

Вы используете Sun JVM? –

+0

Вопрос только в том, сколько основной памяти у вашей машины и сколько бесплатно при запуске вашей программы? – ReneS

+0

Хост имеет память 32G. Хотя, «топ» показывает только несколько Gigs свободной памяти, программа java может удобно разместить 10G. –

ответ

2

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

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

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

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

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

0

Я использовал солнечный vm и начал с минимального набора до 14 концертов, и это начинается с этого. может быть, и должен попробовать установить оба XMS и значение XMX к тому же амт, то есть попробовать this- -Xms3072m -Xmx3072m

0

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

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

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

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

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

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

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

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

3

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

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

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

Попробуйте!

Смежные вопросы