Ответ 1
Фактически нормальный GC запускается, когда молодое поколение заполнено (а не вся куча), и основной GC запускается, когда в пространстве оставшихся нет места, поэтому некоторые объекты необходимо перенести в старое поколение.
Вопрос в основном содержится в названии.
Скажите, что у вас есть приложение, достигшее предела JVM -Xmx. Когда это приложение требует больше памяти, сбор мусора вынужден? (в JVM HotSpot)
Вторая нечеткая вещь, которую я не могу объяснить, заключается в том, что в настоящее время у меня есть сервер приложений, который работает с -Xmx = 2048m, команда "top" (по Linux) сообщает 2.7g для своего процесса.
Итак, как/когда приложение может превышать его -Xmx?
Спасибо,
Фактически нормальный GC запускается, когда молодое поколение заполнено (а не вся куча), и основной GC запускается, когда в пространстве оставшихся нет места, поэтому некоторые объекты необходимо перенести в старое поколение.
Параметр Xmx указывает только размер кучи. Процесс Java занимает больше памяти, так как куча является лишь частью процесса Java, я думаю, у вас также есть другие вещи, которые Java-процесс содержит как родные библиотеки, perm gen и также собственные распределения памяти, сделанные приложением.
Вот хорошая статья, описывающая распределение памяти: http://www.ibm.com/developerworks/java/library/j-nativememory-linux/
Это обычно так, хотя обычно GC запускается гораздо раньше, в зависимости от используемого вами коллекционера мусора.
Да, JVM, безусловно, вызовет GC, если достигнет предела кучи (и, вероятно, намного раньше). Если это не поможет, он будет бросать OutOfMemoryError
s.
Причина, по которой вы наблюдаете большее потребление памяти процесса, заключается в том, что параметр -Xmx
ограничивает пространство кучи Java (где выделены объекты Java). Еще несколько областей памяти, используемых JVM, дополнительно: пространство для стеков потоков, "PermGen" (где хранятся классы и их код), "прямая" память, выделенная через ByteBuffers
, память, выделенная собственными библиотеками и т.д. Для некоторых из этих дополнительных областей памяти существуют другие параметры конфигурации, которые позволяют ограничить их, например -Xss
, но некоторые из них даже не контролируют JVM.
Да, если вы еще не найдете память, это вызовет ошибку OutOfmemory. Я так понимаю.
IIRC гарантируется, что полный GC будет выполнен до того, как будет сброшен OutOfMemoryError
. Поскольку превышение предела размера кучи должно приводить к такой ошибке, это означает, что вы всегда будете иметь хотя бы один полный цикл GC, когда предел достигнут.
Сбор мусора - довольно большая площадь, но то, что вы говорите, верно для полных коллекций (есть другие типы)
Одна вещь, о которой нужно знать, это то, что -Xmx устанавливает максимальный размер кучи, но есть также -Xms, который представляет собой размер кучи минимальной суммы. Ваше приложение может начинаться с минимально сконфигурированного. Затем, если используемая память достигает этого, она вызовет полную сборку мусора и увеличит количество доступной кучи от минимального (-Xmx) до некоторого значения, которое меньше или равно максимальному (-Xmx). Это может произойти несколько раз, пока не будет достигнут максимум. После этого он больше не может увеличить кучу, но сбор мусора будет продолжаться, когда этот максимум будет достигнут.