Почему Java использует статическую кучу, а не позволяет произвольное количество памяти?


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

3 4

3 ответа:

В спецификации JVM нет причин, по которым размер кучи должен быть задан заранее, за исключением того, что это был выбор разработчиков. Спецификация гласит: "реализация виртуальной машины Java может предоставить программисту или пользователю контроль над начальным размером кучи, а также, если куча может быть динамически расширена или сокращена, контроль над максимальным и минимальным размером кучи."

Другие ответы здесь просто неверны: "куча может быть фиксированной размер или может быть расширен в соответствии с требованиями вычисления и может быть сокращен, если большая куча становится ненужной."

Источник: спецификация виртуальной машины Java, Java SE 7 Edition. Раздел 2.5.3, " Куча.- Это страница 13 в печатном издании.

Фрагментация-это огромная проблема в распределении памяти, как и голод памяти. Это намного проще и менее подвержено ошибкам, если вы можете выделить и зарезервировать необходимую память, особенно в серверной среде. При предварительном выделении памяти у вас также есть более высокая вероятность того, что большая часть вашей памяти будет непрерывно выделяться (не гарантируется, спасибо @mttdbrd), что может быть быстрее для доступа.

Возвращаясь к тому времени, когда Java только начиналась, установки с более чем 1 ГБ Оперативная память была в значительной степени неслыханной, вместо этого, мы должны были работать с машинами, которые имели всего лишь 256 МБ оперативной памяти, иногда даже меньше! Соедините это с тем, насколько медленной была оперативная память, и это имело гораздо больше смысла, чтобы иметь возможность читать и писать в надежде на соседние блоки. Вы также не постоянно забиваете ОС, чтобы дать вам больше оперативной памяти, а затем снова выпускаете ее, освобождая (тогда) драгоценные циклы процессора.

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

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

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

Когда ваш код начинает работать, JVM уже создан и настроен. Кроме того, это ограничение гарантирует, что программа не будет забирать все доступные системные ресурсы, нарушая нормальное функционирование других приложений на сервере, независимо от того, насколько плох ее код. ;)