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

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

Если вы долго размышляете об общем способе задать этот вопрос (и не найдя его), я просто спрошу его как конкретный пример:

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

У меня на компьютере установлена ​​стандартная версия JVM версии 7 для Hotspot. Если в данный момент есть достаточно программ, которые работают только 400 Мб из 1 Гб, и я запускаю в это время программу Java со следующими флагами JVM:

java -Xms256m -Xmx512m -jar myJar.jar

Что происходит?

а. JVM не запускается сразу, потому что он попытается выделить всю память 512 Мбайт и потерпеть неудачу (из-за того, что на данный момент недостаточно доступной памяти)?

если запускается JVM:

если в какой-то момент для запуска Java-процесса потребуется более 400 МБ памяти (а там еще 400 Мб свободной памяти, кроме того, что уже используется в текущем Java-процессе), что произойдет:

В. приведет ли процесс Java с OutOfMemroyError?

С. не будет ли он с другой (стандартной) ошибкой?

Д. это поведение undefined?

4b9b3361

Ответ 1

-Xmx определяет максимальный размер кучи. Это не гарантирует, что на нем столько памяти или нет. Это гарантирует, что куча никогда не будет больше, чем заданное значение. Тем не менее, вариант B.), произойдет outOfMemoryError.

Ответ 2

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

Мой первый ответ был бы, если вы не говорите о телефоне, я получаю больше памяти. Вы можете купить 16 ГБ (бит = бит, B = байт) за менее чем 100 долларов.

JVM не запускается сразу, потому что он попытается выделить все 512 МБ памяти и сбой (из-за того, что на данный момент недостаточно доступной памяти)?

Это может произойти, если ваша система не имеет 512 МБ (плюс некоторые накладные расходы), поскольку она выделяет непрерывную виртуальную память, используемую для кучи при запуске.

Даже если у вас 550 МБ бесплатно, программа может не запускаться, так как ей нужно загрузить больше, чем просто кучу.

произойдет сбой процесса Java с помощью OutOfMemoryError?

Это может произойти, если ваша программа использует 512 МБ во время работы, независимо от объема памяти вашего компьютера. Эта ошибка возникает только после запуска JVM. Вы не получите эту ошибку, если она не может быть запущена.

произойдет ли с другой (стандартной) ошибкой?

Это возможно, если вы закончили свободное пространство после запуска программы. Это редко и происходит только на сильно перегруженной машине. То, что я видел, - это сбои JVM из-за сбоя ОС низкого уровня для выделения памяти.

Обновление Java 6 25 Авария VM: недостаточная память

Ответ 3

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

Итак, по существу, "B. Ошибка процесса Java с помощью OutOfMemroyError".

Ответ 4

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

Если вы можете запустить JVM, вы можете указать ограничение на кучу пространства с -Xmx. Это не означает, что вся куча будет выделена JVM при запуске - это всего лишь внутренний предел. Если JVM захочет увеличить кучу пространства, но памяти недостаточно, или вам нужно больше кучи, чем указано -Xmx, вы получите OutOfMemoryError в текущих программах Java.

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

Ответ 5

Процесс JVM будет запускаться в виртуальной памяти, поэтому вопрос о распределении других запущенных процессов имеет значение, но не полностью детерминирован.

Когда JVM не может выделять больше памяти (по какой-либо причине), сам процесс не заканчивается, а скорее начинает метать OutOfMemoryError внутри JVM, но не является внешним для JVM. Другими словами, JVM продолжает работать, но программы, запущенные в JVM, обычно терпят неудачу, потому что большинство из них не справляются с низкими требованиями к памяти. В этом довольно распространенном случае, когда программа ничего не делает для обработки ошибки, JVM завершит работу программы и завершит ее. В конечном счете это происходит из распределения памяти, но не напрямую. Возможно, что часть кода вернется в состояние низкой памяти и продолжит работу.

И другие указали, иногда бывает, что сам JVM плохо обрабатывает низкую память, но это довольно экстремальное условие.