Как уменьшить внутренние издержки Sun / Oracle JVM? - PullRequest
3 голосов
/ 18 октября 2011

Эта проблема, в частности, касается Sun Java JVM, работающей в Linux x86-64 .Я пытаюсь выяснить , почему Sun JVM занимает так много физической памяти системы, даже когда я установил ограничения Heap и Non-Heap .

Программа, которую я запускаю, - Eclipse3.7 с несколькими плагинами / функциями.Наиболее часто используемые функции - это PDT, EGit и Mylyn.Я запускаю Eclipse со следующими переключателями командной строки:

-nosplash -vmargs -Xincgc -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -XX:MaxPermHeapExpansion=10m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseParNewGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=5 -XX:GCTimeRatio=49 -XX:MaxGCPauseMillis=50 -XX:GCPauseIntervalMillis=1000 -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DoEscapeAnalysis -XX:+UseCompressedOops -XX:+AggressiveOpts -Dorg.eclipse.swt.internal.gtk.disablePrinting

Особо следует отметить следующие переключатели:

-Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m

Эти переключатели должны ограничивать кучи JVM до максимумаот 200 МБ и без кучи до 150 МБ («Постоянная генерация CMS» и «Кэш кода» в соответствии с маркировкой JConsole).Логически JVM должна занимать всего 350 МБ плюс внутренние издержки, требуемые JVM.

В действительности JVM требует 544,6 МБ для моего текущего процесса Eclipse, вычисленного с помощью ps_mem.py (http://www.pixelbeat.org/scripts/ps_mem.py), который вычисляет реальные страницы физической памяти, зарезервированные ядром Linux 2.6+. Это внутренние издержки Sun JVM, составляющие 35% или примерно 200 МБ!

Любые подсказкио том, как уменьшить эти издержки?

Вот дополнительная информация:

$ ps auxw
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
me       23440  2.4 14.4 1394144 558440 ?      Sl   Oct12 210:41 /usr/bin/java ...

И, согласно JConsole, процесс использовал 160 МБ кучи и 151 МБ без кучи.

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

Обновление: после публикации вопроса я нашел предыдущийсообщение для SO: Почему Sun JVM продолжает потреблять все больше RSS-памяти, даже когда размеры кучи и т. д. стабильны? Похоже, мне следует использовать pmap для исследования проблемы.

Ответы [ 3 ]

3 голосов
/ 18 октября 2011

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

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

1 голос
/ 18 октября 2011

Затмение - это память и процессор.В дополнение к библиотекам классов Java все низкоуровневые графические интерфейсы обрабатываются собственными системными вызовами, поэтому у вас будет существенная «родная» библиотека JNI для выполнения вызовов низкоуровневых терминов X, связанных с вашим процессом.предлагает миллионы полезных функций и множество помощников, чтобы ускорить ваши повседневные задачи программирования - но постный и означает, что это не так.Любое сокращение памяти или ресурсов, вероятно, приведет к заметному замедлению.Это действительно зависит от того, сколько вы цените свое время по сравнению с памятью вашего компьютера.

Если вы хотите бережливость, а значит, gvim и make непобедимы.Если вы хотите дополнить код, выполнить автоматическую сборку и т. Д., Вы должны рассчитывать на это за счет дополнительных ресурсов.

0 голосов
/ 18 октября 2011

Если я запускаю следующую программу

public static void main(String... args) throws InterruptedException {
    for (int i = 0; i < 60; i++) {
        System.out.println("waiting " + i);
        Thread.sleep(1000);
    }
}

с ps auwx отпечатками

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
500      13165  0.0  0.0 596680 13572 pts/2    Sl+  13:54   0:00 java -Xms64m -Xmx200m -XX:NewSize=8m -XX:PermSize=80m -XX:MaxPermSize=150m -cp . Main

Объем используемой памяти составляет 13,5 МБ. Существует около 200 МБ разделяемых библиотек, что соответствует размеру VSZ. Остальное можно учесть в max heap, max perm gen с накладными расходами для стеков потоков и т. Д.

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

Учитывая, что вы можете купить 16 ГБ примерно за 100 долларов, знаете ли вы, что это действительно проблема?

...