2015-09-08 5 views
28

Я бегу Eclipse 4.3 с Java 7 JRE. Когда я обновляюсь до Java 8 JRE, Eclipse внезапно потребляет больше памяти. Если я запустил Eclipse с JRE 7 прямо в мое рабочее пространство, он выделяет 600 МБ ОЗУ в соответствии с диспетчером задач. Когда я использую JRE 8, это значение составляет 750 МБ.Java 8 выделяет слишком много памяти

Хуже того, если я запускаю большую Java-программу, которая обычно выделяет около 10 ГБ ОЗУ с JRE 7, переключение на JRE 8 заставляет его выделять 12 ГБ ОЗУ.

Кто-нибудь знает, что вызывает дополнительное выделение ОЗУ? Я проверил настройки различных опций, но с нулевым успехом:

-XX:ReservedCodeCacheSize= 
-XX:MaxMetaspaceSize= 
-XX:MetaspaceSize= 
... 
+3

Какой номер в диспетчере задач вы смотрите? – the8472

+0

Зачем думать об этом с помощью этих очень специальных опций 'ReservedCodeCacheSize',' MaxMetaspaceSize' или 'MetaspaceSize' - это путь? Вы проверили, что эти специальные области памяти являются причиной более высокого потребления памяти, а не * обычного размера кучи? Кроме того, какой смысл Eclipse потреблять 750 МБ вместо 600 МБ? Я был бы счастлив, если бы Eclipse был когда-нибудь таким экономным на моей машине ... – Holger

+4

действительно, мое затмение обычно колеблется в 2 ГБ оперативной памяти (мне нужно иногда увеличивать значение по умолчанию), а java-приложения, которые используют TEN GIGABYTES, безусловно, ошибочны по дизайну ; вы не должны использовать такое приложение. Нет такой вещи, как «большая Java-программа», если вам удастся получить размер JAR заметно выше, чем несколько сотен МБ, вы уже создаете массивные рамки приложений - Java действительно эффективна с точки зрения размера файла, вы не будете когда-либо достигли гигабайтного барьера, если вы не ошибаетесь. – specializt

ответ

9

В пути вопрос задают

почему Java 8, выделение слишком много памяти на моей машине

Я не думаю, кто-нибудь сможет ответить, однако есть несколько рекомендаций, которые могут помочь. Учитывая, что вы измеряете память через диспетчер задач, вас интересует общий используемый RSS. Так

  • Шаг 1: Сравнение виртуальной машины Java по умолчанию между версией выполняющиеся. Вы можете получить их с помощью команды java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version для обоих jdks. Используя сортировку текста в верхней части вывода, вы сможете получить хороший diff, используя любой инструмент сравнения. Такие вещи, как изменение коллектора GC коллектора и размера стека потоков, очень сильно повлияют на окончательный RSS.
  • Шаг 2: Измерение распределения для каждого пула памяти. В общей общем объеме памяти, используемой Java может быть вычислено с использованием heap + metasize + code cache + native + (thread_stack_size * maximum_number_of_threads)
    • динамической памяти легко измеримы (и может быть легко по сравнению !!) зрелых инструментами (Eclipse Memory Analyzer, VisualVM и т.д.). Если у вас есть память Увеличение площади кучи - вам очень повезло. В дополнительных визуальных vm вы можете установить плагин, который будет показывать значения всех пулов памяти, доступных через jmx.
    • metasize (aka permgen in jdk < 8) должно быть более/менее равно, и может быть найдено с помощью jmap tool. Не нужно играть с флагом, вы можете получить номер и просто сравнить каждый раз, когда он увеличивается или нет.
    • Code cache: в дополнение к зарезервированному кешу кода вы можете установить начальный кеш кода (и это повлияет на то, сколько RSS используется).
    • родной: это немного черных овец. Если все остальные пулы памяти равны (память падает на 2 ГБ), потерянная память должна быть где-то в родной области. Единственный инструмент, о котором я знаю, - jcmd, и он имеет обширную документацию в документах oracle.

Нетехническое - в то время как различные варианты настройки для того, чтобы уменьшить память может помочь, шансы получить правильные значения близки к нахождению иголки в стоге сена. Я бы порекомендовал иметь о том, как RSS используется в java. Эти знания будут полезны уже несколько лет!

Пожалуйста, дайте мне знать, когда вам нужны более конкретные ссылки или лучшее объяснение. А также...удачи в вашем квесте ;-)

+0

Я не вижу увеличения памяти кучи и памяти метапасса при сравнении JDK7 и JDK8. Я делал измерения с помощью «jvisualvm». Установка ReservedCodeCacheSize обратно до 48 МБ, как и значение по умолчанию в JRE7, оказывает минимальное влияние.Это родная память растет в размерах. – RegedUser00x

+0

Являются ли обе биты 64 (или 32) jdks? Спросите, потому что вы не указали это. –

+0

Да, я использую только 64-разрядные: 64-разрядные JDK7, 64-разрядные JDK8, 64-разрядные JRE7 и 64-разрядные JRE8. – RegedUser00x

1

Я могу подтвердить, что веб-приложение, над которым я работаю (Jetty, Struts2, JDBC), потребляет около 300 МБ больше ОЗУ (1.2G) сразу после запуска при работе в JRE 1.8.0_72 по сравнению с JRE 1.7.0_80. Приложение работает на Centos 6 x64 и делает измерения памяти максимально прозрачными. Я отключил swap и установил -Xms равным -Xmx (40% доступной ОЗУ). Я использовал dstat --top-mem или top -m, чтобы получить общую память, потребляемую процессом java.

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

10 Nov 21:29:54 мое ядро: Из памяти: Убить процесс 26610 (Java) счет 570 или жертву ребенка

Когда я запускаю бесконечный цикл из bash, который вызывает 4 параллельных веб-клиента, которые подключаются к приложению (= установить новое TCP-соединение), запросить статус приложения и отключить, тогда общая память, потребляемая приложением, поднимается примерно на 100-200 KBs каждую минуту. Каждый клиент выполняет 6-10 запросов в минуту. Используемый размер памяти кучи стабилен.

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