Почему делает JVM Sun, продолжают использовать памяти RSS, даже когда "куча", и т.д. размеры стабильны?

"Поле" укусило на имя fieldset, относится к <form> поля.

Используя fieldset внешний form с для группировки aribtrary данных является явно семантическим неправильным употреблением.

Однако Ваш HTML проверит, и Бог не будет Уничтожать Котенка.

33
задан Community 23 May 2017 в 12:09
поделиться

4 ответа

Просто идея: буферы NIO размещаются вне JVM.

РЕДАКТИРОВАТЬ: По состоянию на 2016 год стоит рассмотреть комментарий @Lari Hotari [ Почему Sun JVM продолжает потреблять все больше памяти RSS, даже когда размеры кучи и т. Д. Стабильны? ], потому что еще в 2009 году в RHEL4 было glibc <2.10 (~ 2.3)

С уважением.

18
ответ дан 27 November 2019 в 18:39
поделиться

RSS представляет страницы, которые активно используются - для Java это в первую очередь живые объекты в куче и внутренние структуры данных в JVM. Вы мало что можете сделать, чтобы уменьшить его размер, кроме как использовать меньше объектов или меньше обрабатывать.

В вашем случае я не думаю, что это проблема. На графике как будто израсходовано 3 мегабайта, а не 3 гига, как вы пишете в тексте. Это действительно мало и вряд ли вызовет пейджинг.

Так что еще происходит в вашей системе? Это ситуация, когда у вас много серверов Tomcat, каждый из которых использует 3M RSS? Вы добавляете много флагов GC. Указывают ли они, что процесс большую часть времени проводит в GC? У вас есть база данных, запущенная на том же компьютере?

Изменить в ответ на комментарии

Что касается размера RSS 3M - да, это казалось слишком низким для процесса Tomcat (я поставил свой флажок, и у него есть один на 89M, который некоторое время не был активен). Однако я не обязательно ожидаю, что это будет> размер кучи, и я, конечно, не ожидаю, что он будет почти в 5 раз больше размера кучи (вы используете -Xmx640) - в худшем случае это должен быть размер кучи + некоторое количество для каждого приложения константа.

Что заставляет меня подозревать ваши числа. Поэтому вместо графика с течением времени запустите следующее, чтобы получить снимок (замените 7429 любым идентификатором процесса, который вы используете):

ps -p 7429 -o pcpu,cutime,cstime,cmin_flt,cmaj_flt,rss,size,vsize

(Отредактировал Стью, чтобы мы могли сформировать результаты по вышеуказанному запросу для информации ps :)

[stu@server ~]$ ps -p 12720 -o pcpu,cutime,cstime,cmin_flt,cmaj_flt,rss,size,vsize
%CPU - - - -  RSS SZ  VSZ
28.8 - - - - 3262316 1333832 8725584

Отредактируйте, чтобы объяснить эти числа для потомков

RSS, как уже отмечалось, - это размер резидентного набора: страницы в физической памяти. SZ содержит количество страниц, доступных для записи процессом (сбор за фиксацию); справочная страница описывает это значение как «очень грубое». VSZ содержит размер карты виртуальной памяти для процесса: доступные для записи страницы плюс общие страницы.

Обычно VSZ немного> SZ и очень сильно> RSS. Эти выходные данные указывают на очень необычную ситуацию.

Уточнение того, почему единственным решением является уменьшение количества объектов

RSS представляет собой количество страниц, находящихся в ОЗУ - страниц, к которым осуществляется активный доступ. В Java сборщик мусора периодически просматривает весь граф объекта. Если этот граф объектов занимает большую часть пространства кучи, то сборщик будет касаться каждой страницы в куче, требуя, чтобы все эти страницы стали резидентными в памяти. GC очень хорошо уплотняет кучу после каждой основной коллекции, поэтому, если вы работаете с частичной кучей, большинство страниц не должны находиться в ОЗУ.

И некоторые другие варианты

Я заметил, что вы упомянули о наличии от сотен до нескольких тысяч потоков. Стеки для этих потоков также будут добавлены в RSS, хотя их не должно быть много. Предполагая, что потоки имеют небольшую глубину вызова (типично для потоков обработчика сервера приложений), каждый из них должен использовать только одну или две страницы физической памяти, даже если за каждый из них взимается комиссия в размере пол-мегагонки.

14
ответ дан 27 November 2019 в 18:39
поделиться

Почему это происходит? Что происходит «под капотом»?

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

В вашем случае возможными причинами проблем могут быть: NIO (уже упоминалось), JNI (уже упомянуто), создание чрезмерного количества потоков.

О JNI вы писали, что приложение не использует JNI, но ... Какой тип драйвера JDBC вы используете? Может быть, тип 2 и протекающий? Это очень маловероятно, как вы сказали, использование базы данных было низким.

Что касается создания избыточных потоков, каждый поток получает свой собственный стек, который может быть довольно большим. Размер стека фактически зависит от виртуальной машины, ОС и архитектуры, например, для JRockit это 256 КБ на Linux x64, Я не нашел ссылки в документации Sun на виртуальную машину Sun. Это напрямую влияет на память потока (память потока = размер стека потока * количество потоков). И если вы создадите и уничтожите много потоков, память, вероятно, не будет использоваться повторно.

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

Если честно, сотни или даже тысячи потоков кажутся огромными для мне. Тем не менее, если вам действительно нужно столько потоков, размер стека потоков можно настроить с помощью параметра -Xss . Это может снизить потребление памяти. Но я не думаю, что это решит всю проблему. Когда я смотрю на реальный график памяти, я склонен думать, что где-то есть утечка.

Это напрямую влияет на память потока (память потока = размер стека потока * количество потоков). И если вы создадите и уничтожите много потоков, память, вероятно, не будет повторно использована.

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

Честно говоря, сотни или даже тысячи потоков кажутся огромными для мне. Тем не менее, если вам действительно нужно столько потоков, размер стека потоков можно настроить с помощью параметра -Xss . Это может снизить потребление памяти. Но я не думаю, что это решит всю проблему. Когда я смотрю на реальный график памяти, я склонен думать, что где-то есть утечка.

Это напрямую влияет на память потока (память потока = размер стека потока * количество потоков). И если вы создадите и уничтожите много потоков, память, вероятно, не будет использоваться повторно.

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

Если честно, сотни или даже тысячи потоков кажутся огромными для мне. Тем не менее, если вам действительно нужно столько потоков, размер стека потоков можно настроить с помощью параметра -Xss . Это может снизить потребление памяти. Но я не думаю, что это решит всю проблему. Когда я смотрю на реальный график памяти, я склонен думать, что где-то есть утечка.

s реальное потребление памяти под контролем?

Если честно, сотни и тысячи потоков кажутся мне огромными. Тем не менее, если вам действительно нужно столько потоков, размер стека потоков можно настроить с помощью параметра -Xss . Это может снизить потребление памяти. Но я не думаю, что это решит всю проблему. Когда я смотрю на реальный график памяти, я склонен думать, что где-то есть утечка.

s реальное потребление памяти под контролем?

Если честно, сотни и тысячи потоков кажутся мне огромными. Тем не менее, если вам действительно нужно столько потоков, размер стека потоков можно настроить с помощью параметра -Xss . Это может снизить потребление памяти. Но я не думаю, что это решит всю проблему. Когда я смотрю на реальный график памяти, я склонен думать, что где-то есть утечка.

3
ответ дан 27 November 2019 в 18:39
поделиться

Текущий сборщик мусора в Java хорошо известен тем, что не освобождает выделенную память, хотя память больше не требуется. Однако довольно странно, что размер RSS увеличивается до> 3 ГБ, хотя размер кучи ограничен 640 МБ. Используете ли вы собственный код в своем приложении или у вас включен собственный пакет оптимизации производительности для Tomcat? В этом случае у вас, конечно, может быть утечка собственной памяти в вашем коде или в Tomcat.

В Java 6u14 Sun представила новый сборщик мусора "Garbage-First", который может освобождать память обратно в операционную систему. если это больше не требуется. Он по-прежнему классифицируется как экспериментальный и не включен по умолчанию, но если это возможный вариант для вас, Я бы попытался перейти на новейшую версию Java 6 и включить новый сборщик мусора с аргументами командной строки «-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC». Это может решить вашу проблему.

1
ответ дан 27 November 2019 в 18:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: