Куча Java - это не что иное, как большая структура данных, управляемая в пространстве кучи процесса JVM.Эти две кучи являются логически отдельными объектами, даже если они занимают одну и ту же память.
JVM зависит от реализации хост-системы malloc()
, которая выделяет память из системы с помощью brk()
.В системах Linux (тоже Solaris) память, выделенная для кучи процесса, почти никогда не возвращается, в основном потому, что она становится фрагментированной и куча должна быть смежной.Это означает, что память, выделенная для процесса, будет монотонно увеличиваться, и единственный способ уменьшить размер - не выделять его в первую очередь.
-Xms
и -Xmx
сообщают JVM, как измерять размеркуча Java заблаговременно, что заставляет его выделять память процесса.Java может собирать мусор до тех пор, пока не погаснет солнце, но эта очистка является внутренней для JVM, и поддержка процесса, возвращаемая ей, не возвращается.Стандартный способ для программы, написанной на C (особенно для JVM, выполняющей для вас Eclipse), выделить память malloc(3)
, которая использует механизм, предоставленный ОС, для выделения памяти процессу и последующего управления отдельными выделениями в этих распределениях.Детали того, как работают malloc()
и free()
, зависят от реализации.
В большинстве разновидностей Unix процесс получает ровно один сегмент данных, который представляет собой непрерывную область памяти с указателями на началои конец.Процесс может отрегулировать размер этого сегмента, вызвав brk(2)
и увеличив указатель конца, чтобы выделить больше памяти, или уменьшив его, чтобы вернуть его в систему. Только конец можно регулировать.Это означает, что если ваша реализация malloc()
увеличивает сегмент данных, соответствующая реализация free()
не сможет уменьшить его, если не определит, что в конце есть место, которое не используется.На практике огромный кусок памяти, выделенный с помощью malloc()
, редко попадает в самый конец сегмента данных при его free()
, поэтому процессы имеют тенденцию монотонно расти.