Конечные переменные-члены делают для лучшего GC? - PullRequest
3 голосов
/ 07 июня 2011

Этот вопрос является продолжением этого , но требует более конкретного сценария.

Допустим, у нас есть следующий класс:

public class Person {
    private Foot left, right;

    public Person(Foot left, Foot right) {
        this.left = left;
        this.right = right;
    }
}

Мне было интересно, сможет ли следующий класс быть оптимизированным с точки зрения GC, если мы превратим его в следующее:

public class Person {
    private final Foot left, right;

    public Person(Foot left, Foot right) {
        this.left = left;
        this.right = right;
    }
}

Если я смотрю на этот класс, я могу сразу сказать, что левая и правая переменные никогда не могут быть установлены в ноль рано. Это означает, что единственное время, когда GC должен будет собрать левый и правый объекты (и уменьшить количество ссылок на него) для этого класса, будет, когда ссылки на родительский класс Person достигнут нуля. Это также должно означать, что он может собирать человека одновременно с тем, как он собирает объекты левой и правой ступней; также приводит к меньшему количеству прогонов и ускорению.

Следовательно, в этом примере означает, что пометка окончательных переменных-членов final означает, что код приведет даже к незначительному ускорению при сборке мусора (или это может быть использовано в качестве точки ускорения)?

Ответы [ 3 ]

7 голосов
/ 07 июня 2011

Присвоение полей не запускает работу сборщика мусора или корректировку подсчета ссылок, потому что Java GC не использует подсчет ссылок (*).Таким образом, ответ заключается в том, что объявление поля как final не повлияет на производительность сборщика мусора.(Фаза трассировки коллектора должна проверить поле, является ли оно final.

. Возможно, что объявление поля final может помочь анализу потока данных компилятора JIT и оптимизациивыборки памяти. Однако было бы плохой идеей использовать это в качестве оправдания для изменения полей на final. Если вы собираетесь это сделать, сделайте это из соображений корректности (то есть, чтобы сделать конструкцию безопасной в параллельном контексте) илипо стилистическим соображениям (т. е. для облегчения понимания и сопровождения кода).

(* Ни одна из основных реализаций Java не использует подсчет ссылок для реализации управления памятью. Теоретически возможно, что кто-то может реализовать JVM, использующую подсчет ссылок, но общепринятым считается, что подсчет ссылок ужасно неэффективен ... не говоря уже о проблемах для параллелизма, циклов сбора и т. д.)

1 голос
/ 07 июня 2011

Единственная причина, по которой Оптимизация ГХ невозможна , заключается в том, что спецификация JVM допускает изменение поля final. *Поля 1010 * final имеют особую семантику в процессе создания объекта, что важно для правильной работы процесса построения в отношении модели памяти Java .Но вы можете нарушить правила и использовать отражение, чтобы изменить его.В этом случае вы не можете полагаться на семантику final поля (относительно модели памяти Java )

страйка : Извините, ребята, яне знаю о чем я говорил. final не имеет значения для GC.даже если final вообще не подлежит изменению, GC не может получить никакой полезной информации об этом факте

0 голосов
/ 07 июня 2011

Сборка мусора Java не работает при подсчете ссылок.Он работает, исследуя объекты на предмет доступности.

...