Обычно нет.
Но как и все: зависит от обстоятельств. GC в Java в наши дни ОЧЕНЬ хорош, и все должно быть очищено очень скоро после того, как он станет недоступным. Это происходит сразу после того, как метод оставлен для локальных переменных, и когда на экземпляр класса больше не ссылаются для полей.
Вам нужно только явно указать null, если вы знаете, что в противном случае на него будет ссылаться. Например, массив, который хранится. Вы можете захотеть обнулить отдельные элементы массива, когда они больше не нужны.
Например, этот код из ArrayList:
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null;
return oldValue;
}
Кроме того, явное обнуление объекта не приведет к тому, что объект будет собран раньше, чем если бы он просто вышел из области действия естественным образом, пока не осталось ссылок.
И то и другое:
void foo() {
Object o = new Object();
}
и:
void foo() {
Object o = new Object();
o = null;
}
Функционально эквивалентны.
System.gc()
он будет удален (при условии, что нет других ссылок, указывающих на этот объект).По моему опыту, чаще всего люди игнорируют ссылки из-за паранойи, а не по необходимости. Вот краткое руководство:
Если объект A ссылается на объект B, и вам больше не нужна эта ссылка, а объект A не имеет права на сборку мусора, вы должны явно обнулить поле. Нет необходимости обнулять поле, если охватывающий объект все равно собирает мусор. Обнуление полей в методе dispose () почти всегда бесполезно.
Нет необходимости обнулять ссылки на объекты, созданные в методе. Они будут очищены автоматически после завершения работы метода. Исключением из этого правила являются случаи, когда вы используете очень длинный метод или какой-то массивный цикл, и вам нужно убедиться, что некоторые ссылки очищены до завершения метода. Опять же, такие случаи крайне редки.
Я бы сказал, что в подавляющем большинстве случаев вам не нужно обнулять ссылки. Пытаться перехитрить сборщика мусора бесполезно. Вы просто получите неэффективный, нечитаемый код.
источник
Хорошая статья - сегодняшний ужас кодирования .
Работа GC заключается в поиске объектов, на которые нет указателей, область их поиска - это куча / стек и любые другие пространства, которые у них есть. Поэтому, если вы установите для переменной значение null, фактический объект теперь никем не указывается и, следовательно, может быть GC'd.
Но поскольку сборщик мусора может не работать именно в этот момент, вы на самом деле ничего себе не покупаете. Но если ваш метод довольно длинный (с точки зрения времени выполнения), он может того стоить, поскольку вы увеличиваете свои шансы на сбор этого объекта сборщиком мусора.
Проблема также может быть усложнена оптимизацией кода: если вы никогда не используете переменную после того, как установили для нее значение null, было бы безопасной оптимизацией удалить строку, которая устанавливает значение null (на одну инструкцию для выполнения меньше). Так что на самом деле вы можете не получить никаких улучшений.
В общем, да, это может помочь, но не будет детерминированным .
источник
По крайней мере, в java это вообще не вуду-программирование. Когда вы создаете объект в java, используя что-то вроде
Foo bar = new Foo();
вы делаете две вещи: во-первых, вы создаете ссылку на объект, а во-вторых, вы создаете сам объект Foo. Пока существует эта или другая ссылка, конкретный объект не может быть удален. однако, когда вы присваиваете этой ссылке значение null ...
bar = null ;
и, предполагая, что ничто другое не имеет ссылки на объект, он освобождается и доступен для gc в следующий раз, когда сборщик мусора пройдет мимо.
источник
Это зависит.
Вообще говоря, чем короче вы храните ссылки на свои объекты, тем быстрее они будут собраны.
Если вашему методу требуется, скажем, 2 секунды для выполнения, и вам больше не нужен объект после одной секунды выполнения метода, имеет смысл очистить все ссылки на него. Если GC обнаружит, что через одну секунду на ваш объект все еще ссылаются, в следующий раз он может проверить его через минуту или около того.
В любом случае, установка всех ссылок на null по умолчанию для меня является преждевременной оптимизацией, и никто не должен этого делать, за исключением особых редких случаев, когда это заметно снижает потребление памяти.
источник
Явная установка ссылки на null вместо того, чтобы просто позволить переменной выйти за пределы области видимости, не поможет сборщику мусора, если только удерживаемый объект не очень большой, где установка его на null, как только вы закончите, является хорошей идеей.
Обычно установка ссылок на null означает для ЧИТАТЕЛЯ кода, что этот объект полностью завершен и не должен больше беспокоиться.
Аналогичного эффекта можно добиться, установив более узкую область применения, установив дополнительный набор скоб.
{ int l; { // <- here String bigThing = ....; l = bigThing.length(); } // <- and here }
это позволяет сборщику мусора bigThing сразу после выхода из вложенных фигурных скобок.
источник
public class JavaMemory { private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6); public void f() { { byte[] data = new byte[dataSize]; //data = null; } byte[] data2 = new byte[dataSize]; } public static void main(String[] args) { JavaMemory jmp = new JavaMemory(); jmp.f(); } }
Выше программу кидает
OutOfMemoryError
. Если раскомментироватьdata = null;
, проблемаOutOfMemoryError
решена. Всегда рекомендуется устанавливать для неиспользуемой переменной значение null.источник
Однажды я работал над приложением для видеоконференцсвязи и заметил огромную разницу в производительности, когда я потратил время на нулевые ссылки, как только объект мне больше не нужен. Это было в 2003-2004 годах, и я могу только представить, что GC с тех пор стал еще умнее. В моем случае каждую секунду сотни объектов приходили и уходили из области видимости, поэтому я заметил сборщик мусора, когда он периодически срабатывал. Однако после того, как я указал на нулевые объекты, сборщик мусора прекратил приостанавливать мое приложение.
Так что это зависит от того, что вы делаете ...
источник
Да.
Из «Программиста-прагматика» с.292:
Установив ссылку на NULL, вы уменьшите количество указателей на объект на один ... (что позволит сборщику мусора удалить его)
источник
Я предполагаю, что OP имеет в виду такие вещи:
private void Blah() { MyObj a; MyObj b; try { a = new MyObj(); b = new MyObj; // do real work } finally { a = null; b = null; } }
В этом случае, не будет ли виртуальная машина пометить их для GC, как только они покинут область видимости?
Или, с другой точки зрения, явная установка для элементов значения null заставит их получить сборщик мусора раньше, чем они это сделают, если они просто выйдут из области видимости? Если это так, виртуальная машина может потратить время на сборку мусора для объекта, когда память в любом случае не нужна, что на самом деле приведет к снижению производительности ЦП, поскольку сборка будет выполняться раньше.
источник
null
влияет на поведение сборщика мусора." Это зависит "
Я не знаю о Java, но в .net (C #, VB.net ...) обычно не требуется назначать нуль, когда вам больше не нужен объект.
Однако учтите, что это «обычно не требуется».
Анализируя ваш код, компилятор .net делает хорошую оценку времени жизни переменной ... чтобы точно сказать, когда объект больше не используется. Поэтому, если вы напишете obj = null, это может выглядеть так, как будто объект все еще используется ... в этом случае назначать null контрпродуктивно.
Есть несколько случаев, когда действительно может помочь присвоение null. Один из примеров: у вас есть огромный код, который выполняется в течение длительного времени, или метод, который выполняется в другом потоке, или какой-то цикл. В таких случаях может помочь присвоение null, чтобы сборщику мусора было легко узнать, что он больше не используется.
Для этого нет жестких правил. Пройдя по указанному выше месту в вашем коде, запустите профилировщик, чтобы узнать, помогает ли он каким-либо образом. Скорее всего, вы не увидите выгоды.
Если вы пытаетесь оптимизировать код .net, то, по моему опыту, тщательная осторожность с методами Dispose и Finalize на самом деле более полезна, чем забота о нулях.
Некоторые ссылки по теме:
http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx
http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx
источник
Даже если бы обнуление ссылки было несколько более эффективным, стоило бы уродства засыпать свой код этими уродливыми обнулениями? Они будут только мешать и скрывать код намерения, который их содержит.
Это редкая кодовая база, у которой нет лучшего кандидата для оптимизации, чем попытка перехитрить сборщик мусора (еще реже встречаются разработчики, которым удается перехитрить его). Скорее всего, ваши усилия будут лучше потрачены на что-то другое, отказавшись от этого грубого парсера Xml или найдя некоторую возможность кэшировать вычисления. Эти оптимизации будет легче измерить количественно и не потребуют от вас засорения кодовой базы шумом.
источник
В будущем выполнении вашей программы значения некоторых элементов данных будут использоваться для компьютерного вывода, видимого вне программы. Другие могут использоваться или не использоваться, в зависимости от будущих (и невозможно предсказать) входов в программу. Другие члены данных могут гарантированно не использоваться. Все ресурсы, включая память, выделенные этим неиспользуемым данным, тратятся впустую. Работа сборщика мусора (GC) состоит в том, чтобы устранить эту потерянную память. Для GC было бы катастрофой устранить то, что было необходимо, поэтому используемый алгоритм мог бы быть консервативным, сохраняя больше, чем строгий минимум. Он может использовать эвристические оптимизации для повышения своей скорости за счет сохранения некоторых элементов, которые на самом деле не нужны. GC может использовать множество потенциальных алгоритмов. Поэтому возможно, что изменения, внесенные в вашу программу, и которые не влияют на правильность вашей программы, тем не менее могут повлиять на работу GC, либо заставляя его работать быстрее, чтобы выполнять ту же работу, либо быстрее определять неиспользуемые элементы. Итак, это изменение, устанавливающее ссылку на объект undd на
null
, по идее не всегда вуду.Это вуду? Сообщается, что для этого есть части кода библиотеки Java. Авторы этого кода намного лучше, чем средние программисты, и либо знают, либо сотрудничают с программистами, которые знают детали реализации сборщика мусора. Так что позволяет предположить , что это иногда польза.
источник
Как вы сказали, есть оптимизации, т.е. JVM знает место, когда переменная использовалась в последний раз, и объект, на который она ссылается, может быть GCed сразу после этой последней точки (все еще выполняется в текущей области). Так что обнуление ссылок в большинстве случаев не помогает GC.
Но это может быть полезно, чтобы избежать проблемы «кумовства» (или «плавающего мусора») ( подробнее читайте здесь или смотрите видео ). Проблема существует из-за того, что куча разделена на старое и молодое поколения, и применяются разные механизмы сборки мусора: второстепенный сборщик мусора (который выполняется быстро и часто используется для очистки молодого поколения) и основной сборщик мусора (который вызывает более длительную паузу для очистки старого поколения). «Кумовство» не позволяет собирать мусор в молодом поколении, если на него ссылается мусор, который уже был закреплен за старым поколением.
Чтобы избежать кумовства, неплохо обнулить ссылки на объект, который предполагается удалить. Вы можете увидеть, как этот метод применяется в классах JDK: LinkedList и LinkedHashMap.
private E unlinkFirst(Node<E> f) { final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC // ... }
источник