Java. Может ли объекты, выполняющие методы, собирать мусор? - программирование
Подтвердить что ты не робот

Java. Может ли объекты, выполняющие методы, собирать мусор?

В Java я сделал следующие вещи, не задумываясь об этом:

public class Main {

    public void run() {
        // ...
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

Однако в последнее время я не уверен, насколько безопасно это делать. В конце концов, после его создания нет ссылки на объект Main (ну, есть ссылка this, но делает ли это подсчет?), Поэтому похоже, что существует опасность того, что сборщик мусора может удалить объект, пока это в середине выполнения чего-то. Поэтому, возможно, метод Main должен выглядеть следующим образом:

    public static void main(String[] args) {
        Main m = new Main();
        m.run();
    }

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

4b9b3361

Ответ 1

Если объектный метод выполняется, значит, кто-то владеет этой ссылкой. Таким образом, нет, объект не может быть GC'd во время выполнения метода.

Ответ 2

По большей части сбор мусора является прозрачным. Это там, чтобы устранить ненужное усложнение ручного управления памятью. Таким образом, это будет не собираться, но то, что на самом деле происходит, более тонкое.

Тривиально, компилятор может полностью исключить конструкцию объекта. (К компилятору я имею в виду компилятор более низкого уровня, чем javac. Байт-коды будут буквальной транслитерацией источника.) Более неясно, сборщик мусора обычно работает в отдельных потоках и фактически удаляет незагруженный объект как метод, на котором он выполняется.

Как это можно наблюдать? Обычный подозреваемый в финалисте. Он может работать одновременно с методом, запущенным на объекте. Как правило, вы сталкиваетесь с этой проблемой с блоками synchronized как в финализаторе, так и в нормальных методах, который вводит необходимые отношения до и после.

Ответ 3

m - это просто переменная, в которой хранится ссылка. Это будет использоваться программистом для использования одного и того же объекта для записи логики на том же объекте.

Во время выполнения программа будет преобразована в OP-CODES/INSTRUCTIONS. Эти INSTRUCTION будут иметь ссылку на объект (это все-таки место для памяти). В случае присутствия m местоположение объекта будет доступно через КОСВЕННУЮ СПРАВКУ. Если m отсутствует, ссылка DIRECT.

Итак, здесь объект используется регистром процессора, независимо от использования ссылочной переменной.

Это будет доступно, пока поток выполнения не будет включен в функцию main().

Кроме того, в соответствии с процессом GC GC только удаляет объекты из памяти, как только GC уверен, что объект больше не будет использоваться.

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

В более простых словах, которые были использованы недавно, будет предоставлена ​​возможность остаться в памяти. Старые объекты будут удалены из памяти.

Итак, учитывая ваш код:

public class Main {

public void run() {
    // ...
}

public static void main(String[] args) {
    new Main().run();
}
}

объект не будет собираться мусором.

Кроме того, для примера попробуйте взглянуть на анонимные примеры классов. Или примеры обработки событий в AWT/SWING.

Там вы найдете много такого, как это.