2015-04-23 3 views
3

В книге Думая на 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 создает объект только тогда, когда он видит для него какое-то «реальное» использование?

ответ

4

Объект будет создан, компилятор байт-кода не будет оптимизировать это. Что происходит во втором случае, так это то, что ваша программа завершает работу до того, как вывод действительно покраснел на ваш терминал (или, может быть, даже до запуска финализатора, вы никогда не знаете, когда на самом деле происходит GC и финализация). Если вы добавите Thread.sleep() после вызова System.gc(), вы увидите вывод.

+1

Если вы вызываете это в цикле, компилятор может в конечном итоге оптимизировать его. – the8472

+0

Действительно, это может быть ДЖИТ: ушел. Я имел в виду компилятор байт-кода, уточню. –

+0

@KristofferE Хорошо, он работает после добавления 'Thread.sleep()'. :-) – dotslash

Смежные вопросы