Как препятствовать объекту то, чтобы быть собранным "мусор"?

Высокий звук + F1 является пользой ярлык ключ для sp_help.

sp_helptext другой положительный герой для получения текста хранимой процедуры.

32
задан 5 revs, 2 users 74% 1 May 2015 в 09:58
поделиться

6 ответов

Удерживать ссылку. Если ваш объект собирается преждевременно, это признак того, что у вас есть ошибка в дизайне вашего приложения.

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

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

public class Singleton {
  private static Singleton uniqueInstance;

  private Singleton() {
    }

  public static synchronized Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqInstance;
  }
}

Изменить: Технически вы можете сохранить ссылку где-нибудь в финализаторе. Это предотвратит сбор объекта до тех пор, пока сборщик снова не определит, что ссылок больше нет. Финализатор будет вызываться не более одного раза, однако вы должны убедиться, что ваш объект (включая его суперклассы) не нужно финализировать после первой коллекции. Однако я бы посоветовал вам не использовать эту технику в реальных программах. (Из-за этого коллеги вроде меня будут кричать «WTF !?»)

  protected void finalize() throws Throwable {
    MyObjectStore.getInstance().store(this);
    super.finalize(); // questionable, but you should ensure calling it somewhere.
  }
32
ответ дан 27 November 2019 в 20:42
поделиться

Если ссылка на объект все еще существует, сборщик мусора не будет. Если на него нет никаких ссылок, вам все равно.

Другими словами, сборщик мусора только собирает мусор. Пусть делает свое дело.

Другими словами - сборщик мусора только собирает мусор. Пусть делает свое дело.

Другими словами - сборщик мусора только собирает мусор. Пусть делает свое дело.

3
ответ дан 27 November 2019 в 20:42
поделиться

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

Очевидно, если вы сохраните ссылку на объект в каком-то долгоживущий контекст, он не будет собран, но рекрутер ОП спрашивал не об этом. Это не то, что происходит в методе finalize.

Что вы можете сделать, чтобы предотвратить сборку мусора из метода finalize, так это написать бесконечный цикл, в котором вы вызываете Thread.yield (); ( предположительно, чтобы предотвратить оптимизацию пустого цикла):

@Override
protected void finalize() throws Throwable { 
    while (true) { 
        Thread.yield(); 
    } 
} 

Моя ссылка - это статья Эллиота Бэка , в которой описывается принудительная утечка памяти этим методом.

Еще один способ, которым методы finalize - зло .

9
ответ дан 27 November 2019 в 20:42
поделиться

Я подозреваю, что вы имеете в виду, если ваш метод finalize хранит ссылку на финализируемый объект. В этом случае (если я правильно понимаю Java Language Spec ) метод finalize никогда не будет запущен повторно, но объект еще не будет обработан сборщиком мусора.

Это не то, что делают в реальной жизни, разве что случайно!

2
ответ дан 27 November 2019 в 20:42
поделиться

Я считаю, что для этого есть образец . Не уверен, что это заводской узор. Но у вас есть один объект, который создает все ваши объекты и содержит ссылку на них. Когда вы закончите с ними, вы отказываетесь от ссылки на них на фабрике, делая вызов явным.

0
ответ дан 27 November 2019 в 20:42
поделиться

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

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

public class Foo {
   static Foo reference;
  ...
  finalize (){ 
     reference = this; 
  }
}

Я сомневаюсь, что это сработает, или это может сработать, но будет зависеть от реализации GC, или будет "неопределенным поведением". Хотя выглядит злобно.

2
ответ дан 27 November 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: