2013-09-14 3 views
-2

Я читал мышление главы java о сборщике мусора, и я узнал пример, который работает один раз на некоторое время. Но я не могу понять, почему.Пример сборщика мусора не содержит

public class Book { 

boolean checkedOut = false; 

Book(boolean checkOut) { 
    checkedOut = checkOut; 
} 

void checkIn() { 
    checkedOut = false; 
} 

@Override 
protected void finalize() { 
    if (checkedOut) { 
     System.out.println("Error: checked out"); 
    } 
    // Normally, you’ll also do this: 
    //super.finalize(); // Call the base-class version 
} 

public static void main(String[] args) { 
    Book novel = new Book(true); 
// Proper cleanup: 
    novel.checkIn(); 
// Drop the reference, forget to clean up: 
    new Book(true); 
// Force garbage collection & finalization: 
    System.gc(); 
    } 
} 

Вызов System.gc() должен заставить финализации объектов, даже если память не поджимает.

Таким образом, почему выходные программы Ошибка: выдан только после выполнения 4-5 подряд? я не могу понять, можете ли вы попытаться разъяснить это, пожалуйста? Я ожидаю, что каждый раз, когда GC называется методом finalize, выполняется также, поэтому каждый раз, когда ошибка проверки должна быть пропущена.

Thanks

+1

Вопрос не ясен. Не могли бы вы объяснить, какое поведение вы ожидаете? –

+0

Не пытайтесь заглянуть в ваш пример, но выполнение 'finalize' не гарантируется. –

+0

yep извините, отредактированный. – LMG

ответ

3

Вы прочитали документацию?

От http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc%28%29

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

(курсив мой)

Он не говорит «после этого разговора, вы гарантированно, что все объекты будут некорневых мелиорировано и их финализаторы выполнены». Вы даете GC предложение, чтобы посмотреть, есть ли какие-либо данные для восстановления, было бы хорошей идеей. Не более того.

(Кроме того, http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#runFinalization%28%29 может быть лучше подходит для того, что вы на самом деле хотите случиться, так как код, который вы показали нам проверяет, выполнил финализации объекта, не был ли сбор мусора объект)

+0

так что только предложение? что я действительно хочу заставить? – LMG

+0

Я имею в виду, что не рекомендуется запускать непосредственно финализацию. – LMG

+0

Зачем вам это нужно? – jalf

1

Вполне возможно, что объект никогда не получает мусор, собранный (и таким образом finalize никогда не вызывается).

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

Нет гарантии, что finalize() будет называться.

ПРИМЕЧАНИЕ: Если вы делаете это для понимания целей, то его штраф, но вы должны избегать вызова System.gc() явно.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не говорю, что это правильный способ сделать это. Я просто попытался подумать, была ли какая-то задержка перед вызовом задержки, возможно, созданный объект будет обнаружен gc и будет собираться каждый раз.

Временное решение (не гарантируется)

Thread.sleep(10000); //try sleeping for a while before giving a call to gc 
// Force garbage collection & finalization: 
    System.gc(); 

Печатный требуемый выход 4 раза подряд на моем окружении.

+0

downvoter позаботиться о компромиссе? –

+4

На какой планете «блокировать поток в течение 10 секунд» полезно обходное решение? – jalf

+0

@jalf Я просто разместил его, так как будет некоторая задержка, прежде чем gc получит шанс запустить. А также я попробовал это в своей среде. Если это кажется расплывчатым, я удалю его? Что ты предлагаешь? –

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