Как написать код, чтобы помочь сборщику мусора - PullRequest
1 голос
/ 30 мая 2019

На собеседовании у меня возник вопрос - «Как помочь сборщику мусора при написании кода?».

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

Есть хороший ответ? Нужно ли делать что-то невероятное, чтобы помочь сборщику мусора?

Ответы [ 3 ]

2 голосов
/ 30 мая 2019

Вопрос сформулирован странно.GC не нуждается в помощи с его работой.Он будет работать с любыми наложенными на него ограничениями или потерпит неудачу, если эти ограничения не будут выполнены.

Конечно, работа может быть изменена, но это не сделано из-за желания облегчить бремя GC -это не человек, которому может быть скучно из-за его работы - но из-за каких-то скрытых мотивов, таких как повышение общей производительности программы.

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

Наивный код может быть более читабельным, но менее производительным.Если ваша цель - легко читаемый код, то выполнение комплексных оптимизаций, снижающих нагрузку на ГХ, может быть непродуктивным, и, следовательно, «помощь ГХ» не является самоцелью.

Теперь, если ваша цель состоит в том, чтобыулучшить некоторые показатели производительности, а затем некоторые оптимизации также включают в себя написание кода, который уменьшает работу, выполняемую подсистемой управления памятью (выделение + сборщик мусора).Некоторые возможные оптимизации: избегать финализаторов, обнаруживать утечки памяти, сокращать ненужные выделения, избегать огромных массивов Object [], настраивать параметры GC, покупать лучшее оборудование и сокращать время жизни объектов.Какая оптимизация применима, зависит от приложения и может быть наилучшим образом определена с помощью профилировщиков, регистрации GC и связанных с ними данных

1 голос
/ 30 мая 2019

Сборщик мусора - это «задача», которая периодически сканирует ваши объекты, чтобы обнаружить то, что не используется (на самом деле это механизм для эмуляции машины с бесконечной памятью).

По этой причине,когда вы держите ссылку на экземпляр объекта, который вам больше не нужен, вы должны установить для него значение null, чтобы сборщик мусора знал, что вы больше не заинтересованы в этом экземпляре (и, возможно, его потомках).

Это не означает, что вы должны установить каждую переменную на null после использования, но вы должны следить за полями.Поскольку Java не имеет шаблона удаления (см. здесь для получения дополнительной информации), вы должны разработать свои API-интерфейсы, чтобы имитировать его: когда вы закончите использовать экземпляр объекта, который содержит ссылку, которую вы хотите освободить, вынеобходимо добавить соответствующий метод для выполнения такого действия.

Рассмотрим следующий пример:

class MyClass1
{
    int Field1;
    int Field2;
    int Field3;
    int Field4;
}

class MyClass2
{
    private MyClass1 m_MyReference;

    public MyClass2()
    {
        m_MyReference = new MyClass1();
    }

    public void DoSomething()
    {
        // do something here that uses m_MyReference.
    }
}

Если удерживается экземпляр MyClass2, но какой-то другой достижимый экземпляр вашей программы (например, одиночный)или какой-либо другой экземпляр, который в данный момент находится в стеке), вы никогда не освободите память, связанную с MyClass1, так как на нее все еще ссылается m_MyReference.

Это плохо?Это зависит от того, что MyClass2 и MyClass1 действительно делают.

Если вы знаете, что MyClass2 может иметь очень большой срок службы, и вы хотите сохранить ссылку на MyClass2, но для освобождения памяти, связанной с MyClass1, вам нужно сделатьчто-то похожее на код ниже:

class MyClass2
{
    private MyClass1 m_MyReference;

    public MyClass2()
    {
        m_MyReference = new MyClass1();
    }

    public void DoSomething()
    {
        // do something here that uses m_MyReference.
    }

    public void Dispose()
    {
        m_MyReference = null;
    }

}

Таким образом, вы предоставляете звонящему способ сообщить, что вы больше не держите ссылку на ненужные вам экземпляры.

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

1 голос
/ 30 мая 2019

Сборщик мусора очень эффективен и ловок в своей работе, но мы можем повысить его способность собирать мусор, указав переменные и объекты на null, которые больше не используются, и на них больше нет ссылок.Во время обработки файлов используйте методы close () и flush ().И при обработке потоков уничтожайте поток, когда он не используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...