2014-02-12 7 views
-2

Дано:нужно больше объяснений финализации(), образец экзамена

class Finalizer { 
    static int x = 0; 
    static boolean gc = false; 
    public static void main(String[] args) { 
     for(x=0; x<100000; x++) { 
      new Finalizer().finalize(); 
     } 
     x = 0; 
     gc = true; 
     System.gc(); 
    } 
    protected void finalize() { 
     if(gc == true) x++; 
     if(x % 10000 == 0) 
      System.out.println(gc + " " + x); 
    } 
} 

которые всегда верно? (Выберите все подходящие варианты.)

A: true will never be an output 
B: true will be output at least ones 
C: If true and false are both output, their respective values for x can be the same. 
D: If true and false are both output, their respective values for x can never be the same. 

Раствор говорит C правильно, и я не понимаю, почему, может кто-то пожалуйста, объясните, что здесь происходит.

+2

Вы пробовали просто запустить код? Каковы были ваши выводы? –

+0

Поскольку вы не сможете запустить этот код на реальном экзамене, я бы рекомендовал отслеживать его вручную (достаточно, чтобы посмотреть, что он делает, а не все 100 000 итераций этого цикла). Это поможет вам понять, что делает код, а затем вы можете понять, почему C является правильным. – forgivenson

+0

Обратите внимание, что если он видит, почему C истинно, он все равно должен понять, почему A и B являются неправильными. (Экзамен говорит, что нужно выбрать _all_ утверждения, которые всегда верны. C и D не могут быть правильными, поскольку они взаимоисключающие.) – ajb

ответ

1

Что происходит: finalize() переопределяет метод в классе Object. javadoc объясняет, когда это вызвано. Когда объект больше не ссылается нигде, он может быть собран в мусор; но , когда это сбор мусора, не определяется языком.

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

В этом примере цикл вызовет new Finalize() 100 000 раз для создания новых объектов Finalize. Каждый раз, когда создается новый объект, он используется для прямого вызова finalize(), но затем он больше не используется, поэтому его можно сразу собрать в мусор. Следствием этого является то, что к тому времени, когда мы дойдем до звонка System.gc(), мы не знаем, сколько объектов осталось Finalize, ожидая сбора мусора, но оно может быть от 0 до 100 000. (На моей машине, это, кажется, 1. То есть, это уже мусор собрали все, кроме одного из объектов, и называется finalize() на них.)

В течение первого цикла, x будет идти от 0 до 999,999 (метод finalize() не будет изменять x), и поэтому вы должны увидеть false x за каждые x, что кратно 10000. (Обратите внимание, что finalize() также может быть вызвана во время выполнения для объектов сборщиком мусора рано, так что в теории это можно увидеть false x больше, чем когда-то же x.)

После первого цикла, если N это количество объектов, которые все еще собираются в мусор, тогда System.gc() должен заставить их всех собирать мусор в этой точке (это не гарантируется); так как x сбрасывается на 0 и finalize()будет прирастить его, то есть x будет идти от 1 до N. (Обратите внимание, что первый finalize() будет увеличиваться x от 0 до 1 до испытания x % 10000.) Вы должны увидеть true x для каждого x в диапазоне от 1 до N , кратной 10000.

Но так как N может быть любым размером от 0 до 100 000, это означает, что мы можем видеть или не видеть никаких выходов true - мы не можем сказать. Вот почему ни A, ни B «всегда верны». Если мы увидим какие-либо выходы true, так как на выходе будет отображаться каждый кратный 10 000 в своем диапазоне, то определенно, что вывод true будет иметь тот же номер, что и предыдущий вывод false, что объясняет, почему C является правильным, а D - нет.

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

  • Нет связанных вопросов^_^