Собирает ли JVM сборку мусора, когда она достигает предела -Xmx?

Вопрос в основном содержится в названии.

Скажите, что у вас есть приложение, достигшее предела JVM -Xmx. Когда это приложение требует больше памяти, сбор мусора вынужден? (в JVM HotSpot)

Вторая нечеткая вещь, которую я не могу объяснить, заключается в том, что в настоящее время у меня есть сервер приложений, который работает с -Xmx = 2048m, команда "top" (по Linux) сообщает 2.7g для своего процесса.

Итак, как/когда приложение может превышать его -Xmx?

Спасибо,

Ответ 1

Фактически нормальный GC запускается, когда молодое поколение заполнено (а не вся куча), и основной GC запускается, когда в пространстве оставшихся нет места, поэтому некоторые объекты необходимо перенести в старое поколение.

Ответ 2

Параметр Xmx указывает только размер кучи. Процесс Java занимает больше памяти, так как куча является лишь частью процесса Java, я думаю, у вас также есть другие вещи, которые Java-процесс содержит как родные библиотеки, perm gen и также собственные распределения памяти, сделанные приложением.

Вот хорошая статья, описывающая распределение памяти: http://www.ibm.com/developerworks/java/library/j-nativememory-linux/

Ответ 3

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

Ответ 4

Да, JVM, безусловно, вызовет GC, если достигнет предела кучи (и, вероятно, намного раньше). Если это не поможет, он будет бросать OutOfMemoryError s.

Причина, по которой вы наблюдаете большее потребление памяти процесса, заключается в том, что параметр -Xmx ограничивает пространство кучи Java (где выделены объекты Java). Еще несколько областей памяти, используемых JVM, дополнительно: пространство для стеков потоков, "PermGen" (где хранятся классы и их код), "прямая" память, выделенная через ByteBuffers, память, выделенная собственными библиотеками и т.д. Для некоторых из этих дополнительных областей памяти существуют другие параметры конфигурации, которые позволяют ограничить их, например -Xss, но некоторые из них даже не контролируют JVM.

Ответ 5

Да, если вы еще не найдете память, это вызовет ошибку OutOfmemory. Я так понимаю.

Ответ 6

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

Ответ 7

Сбор мусора - довольно большая площадь, но то, что вы говорите, верно для полных коллекций (есть другие типы)

Одна вещь, о которой нужно знать, это то, что -Xmx устанавливает максимальный размер кучи, но есть также -Xms, который представляет собой размер кучи минимальной суммы. Ваше приложение может начинаться с минимально сконфигурированного. Затем, если используемая память достигает этого, она вызовет полную сборку мусора и увеличит количество доступной кучи от минимального (-Xmx) до некоторого значения, которое меньше или равно максимальному (-Xmx). Это может произойти несколько раз, пока не будет достигнут максимум. После этого он больше не может увеличить кучу, но сбор мусора будет продолжаться, когда этот максимум будет достигнут.