Когда сборка мусора Java освобождает выделение памяти? - PullRequest
14 голосов
/ 23 июля 2010

Я создал объект на Java с именем FOO. FOO содержит большой объем данных ... Я не знаю, скажем, для текстового файла размером в 10 мегабайт, который я вытащил в оперативную память для манипуляции. (Это только пример)

Это явно огромное количество места, и я хочу освободить его из памяти. Я установил FOO в NULL.

Освободит ли это пространство в памяти автоматически? или же Будет ли память, занятая загруженным текстовым файлом, сохраняться до автоматической сборки мусора?

Ответы [ 6 ]

15 голосов
/ 23 июля 2010

Когда вы устанавливаете ссылку любого объекта на null, он становится доступным для сборки мусора.Он все еще занимает памяти до тех пор, пока сборщик мусора не запустится.Нет никаких гарантий относительно того, когда GC будет работать, за исключением того, что он определенно будет запускаться и восстанавливать память из недоступных объектов до того, как будет выдан OutOfMemoryException.

Вы можете вызвать System.gc () для запроса сборки мусора, однаковот что это такое - просьба.GC может работать по своему усмотрению.

Использование WeakReference может помочь в некоторых случаях.См. эту статью Брайана Гетца.

8 голосов
/ 23 июля 2010

На самом деле объект не называется FOO.FOO - это имя переменной, которая не является объектом;переменная содержит ссылку на объект.Может быть несколько различных переменных, содержащих ссылки на один и тот же объект.

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

Когда вы устанавливаете FOO = null, предполагая, чтоFOO содержит в этой точке последнюю доступную ссылку на объект, затем память освобождается немедленно , в следующем смысле: в тот самый тактовый цикл, в котором null установлен в FOO,объект становится недоступным.Следовательно, сборщик мусора заметит этот недостижимый объект и освободит соответствующий блок памяти;то есть GC сделает это в следующий раз, когда его можно будет запустить.Конечно, реальные биты, которые составляют объект, могут немного задерживаться в памяти;но этот блок, тем не менее, «свободен», так как распределитель памяти автоматически запускает GC, когда свободной памяти недостаточно.С точки зрения приложения, объект так же хорош, как мертвый, и соответствующая память свободна, так как эта память будет использоваться повторно, когда приложение понадобится ей в следующий раз.Все это происходит автоматически.

В отношении операционной системы все немного сложнее.Если недоступный объект является свободной памятью с точки зрения приложения, он все еще, с точки зрения ОС, является блоком ОЗУ, выделенным для запущенного процесса.Этот блок ОЗУ может быть возвращен в ОС только тогда, когда GC (который на уровне ОС является частью процесса) фактически выполняется, замечает, что объект недоступен, и снисходит, чтобы вернуть блок ОС.,Когда GC сильно работает, зависит от технологии GC и от того, как приложение распределяет объекты;также, некоторые GC никогда не будут возвращать блок ОС вообще (GC знает, что блок свободен, распределитель памяти будет использовать его по своему усмотрению, но не в других процессах).

System.gc() являетсянамек на виртуальную машину, чтобы она теперь запускала GC.Формально это только подсказка, и виртуальная машина может игнорировать ее.На практике он запускает GC, если виртуальная машина не проинструктирована не подчиняться таким командам (с JVM от Sun это зависит от конкретного флага командной строки).Даже если GC работает, он не обязательно возвращает память операционной системе.System.gc() не очень полезно.

5 голосов
/ 23 июля 2010

Обратите внимание, что даже вызов System.gc () не гарантирует, что JVM сделает это сразу.

System.gc () - это просто запрос, и нет гарантии, что он вступит в силу немедленно.

5 голосов
/ 23 июля 2010

Установка foo = null; не означает, что foo будет немедленно очищен от мусора. Вместо этого он будет собран при следующем запуске GC, если это возможно. Когда foo собирается, любые объекты, для которых он содержит единственную ссылку, также будут иметь право на сбор и, следовательно, собираемые.

0 голосов
/ 23 июля 2010

Сборщик мусора освободит память после того, как вы «уничтожите» ссылку. i.3 Установка ссылки на объект на ноль. Вы можете использовать опцию принудительной сборки мусора, но вы должны использовать ее с осторожностью. Сборщик мусора предназначен для использования оптимизированного расписания, поэтому вызов System.gc () может разрушить ритм и, возможно, снизить производительность из-за ненужного переключения задач.

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

0 голосов
/ 23 июля 2010

Нет никаких гарантий, что JVM сделает это сразу, вы можете попробовать форсировать его, используя System.gc ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...