В книге Думая на Java, автор предоставляет технику принудительной сборки мусора объекта. Я написал подобную программу, чтобы проверить это (я на Open JDK 7):Объясните это поведение System.gc()
//forcing the garbage collector to call the finalize method
class PrintMessage
{
private String message;
public PrintMessage (String m)
{
this.message = m;
}
public String getMessage()
{
return this.message;
}
protected void finalize()
{
if(this.message == ":P")
{
System.out.println("Error. Message is: " + this.message);
}
}
}
public class ForcingFinalize
{
public static void main(String[] args)
{
System.out.println((new PrintMessage(":P")).getMessage());
System.gc();
}
}
Хитрость, как кажется мне, это создать новую ссылку на объект, а не назначать его: new PrintMessage();
.
Вот что меня озадачивает. Когда я скомпилировать и запустить эту программу, я получаю следующий ожидаемый результат:
:P
Error. Message is: :P
Однако, если изменить первую строку моей главной функции(), как это:
(new PrintMessage(":P")).getMessage();
Я не вижу любой выход. Почему System.gc()
вызывает сборщик мусора только тогда, когда я отправляю вывод на стандартный вывод? Означает ли это, что JVM создает объект только тогда, когда он видит для него какое-то «реальное» использование?
Если вы вызываете это в цикле, компилятор может в конечном итоге оптимизировать его. – the8472
Действительно, это может быть ДЖИТ: ушел. Я имел в виду компилятор байт-кода, уточню. –
@KristofferE Хорошо, он работает после добавления 'Thread.sleep()'. :-) – dotslash