На самом деле объект не называется FOO.FOO - это имя переменной, которая не является объектом;переменная содержит ссылку на объект.Может быть несколько различных переменных, содержащих ссылки на один и тот же объект.
Сборщик мусора работает путем автоматического обнаружения недоступных объектов: это объекты, которые приложение больше не может использовать, поскольку оно безвозвратно забыло, гдеони есть (приложение может получить доступ к любому объекту, на который у него есть ссылка, включая ссылки, хранящиеся в поле в объектах, к которым оно имеет доступ, и т. д.).
Когда вы устанавливаете FOO = null
, предполагая, чтоFOO
содержит в этой точке последнюю доступную ссылку на объект, затем память освобождается немедленно , в следующем смысле: в тот самый тактовый цикл, в котором null
установлен в FOO
,объект становится недоступным.Следовательно, сборщик мусора заметит этот недостижимый объект и освободит соответствующий блок памяти;то есть GC сделает это в следующий раз, когда его можно будет запустить.Конечно, реальные биты, которые составляют объект, могут немного задерживаться в памяти;но этот блок, тем не менее, «свободен», так как распределитель памяти автоматически запускает GC, когда свободной памяти недостаточно.С точки зрения приложения, объект так же хорош, как мертвый, и соответствующая память свободна, так как эта память будет использоваться повторно, когда приложение понадобится ей в следующий раз.Все это происходит автоматически.
В отношении операционной системы все немного сложнее.Если недоступный объект является свободной памятью с точки зрения приложения, он все еще, с точки зрения ОС, является блоком ОЗУ, выделенным для запущенного процесса.Этот блок ОЗУ может быть возвращен в ОС только тогда, когда GC (который на уровне ОС является частью процесса) фактически выполняется, замечает, что объект недоступен, и снисходит, чтобы вернуть блок ОС.,Когда GC сильно работает, зависит от технологии GC и от того, как приложение распределяет объекты;также, некоторые GC никогда не будут возвращать блок ОС вообще (GC знает, что блок свободен, распределитель памяти будет использовать его по своему усмотрению, но не в других процессах).
System.gc()
являетсянамек на виртуальную машину, чтобы она теперь запускала GC.Формально это только подсказка, и виртуальная машина может игнорировать ее.На практике он запускает GC, если виртуальная машина не проинструктирована не подчиняться таким командам (с JVM от Sun это зависит от конкретного флага командной строки).Даже если GC работает, он не обязательно возвращает память операционной системе.System.gc()
не очень полезно.