Страницы

Поиск по вопросам

четверг, 5 декабря 2019 г.

Android Studio пишет, что переменной присвоено значение null, но она нигде не используется

#java #android


Вопрос назрел случайно, когда перешел с Eclipse на AS. Компилятор пишет предупреждение
(указал в топике). Но меня это смущает. Смысл вот в чем. Есть некий класс, я получаю
его экземпляр. Использую его методы. После использования переменную, которая получала
этот экземпляр обнуляю (=null).

MyPreferences pref = new MyPreferences();
pref.loaddata();
...использую методы класса MyPreferences
pref = null;


Вот на последней строчке AS предупреждает. Но раньше я читал такую фразу, что "Android
не любит утечки ресурсов поэтому освобождаем переменную....и присваивали ей null".
Помогите разобраться как правильно писать... спасибо.
    


Ответы

Ответ 1



В том и интерес области видимости и управления памятью в JVM. К примеру, Вы выполняете в своем методе все вышеописанное, после выполнения кода и выхода из метода, ссылки на объект теряются и через время он уничтожается сборщиком мусора. По сути, Вы дописываете лишнее, на что AS и указывает. Совсем другая история, если MyPreferences pref Вы укажете вне метода, переменной класса. Вот тогда pref = null; действительно необходимо для обнуления ссылок для последующего уничтожения объекта сборщиком мусора. private void myMethod() { MyPreferences pref = new MyPreferences(); pref.loaddata(); ...использую методы класса MyPreferences } против public class MyClass extends NotMyClass { MyPreferences pref; ... private void myMethod() { pref = new MyPreferences(); pref.loaddata(); ...использую методы класса MyPreferences pref=null; } }

Ответ 2



Установка null лишь указывает сборщику, что вы объект не используете. Это не вызывает GC сразу же и т.п. Как VAndrJ правильно написал, всё зависит от видимости переменной. Вот только его пример не должен использоваться в реальном проекте: public class MyClass extends NotMyClass { MyPreferences pref; ... private void myMethod() { pref = new MyPreferences(); pref.loaddata(); ...использую методы класса MyPreferences pref=null; } } Это проблема архитектуры. Сложно представить кейс, когда такое могло бы понадобиться. Обычно поля класса живут вместе с самим классом (консистентность, все дела). И когда у вас уже не будет ссылки на сам объект, то всего его внутренние поля будут уничтожены. По поводу же установки переменных в null, порой это даже вредно. Если вы в играх будете всегда явно устанавливать объекты в null, то gc будет работать дольше, так как надо больше освободить. Чтобы оптимизировать в этом отношении игру, необходимо использовать пулы объектов, чтоб gc на них не вызывался вообще. Вообще, почитайте хорошую статью от ibm. В ней ясно дают понять, что порой зануление ссылок может даже сделать хуже.

Ответ 3



принудительно присваивать null, когда поле более не требуется\класс не используется\активити закрывается, нужно только static-полям с завязкой на Context, чтобы избежать утечек памяти, так как имея static на внешний класс, сборщик мусора не уничтожит объект. Так же нужно следить за закрытием курсоров, БД и тп. С остальным разберется сборщик мусора.

Ответ 4



Это ответственность сборщика мусора - находить неиспользуемые более объекты и удалять их. Принудительное обнуление переменных не дает каких-либо преимуществ и просто не имеет смысла, на мой взгляд. Единственный вариант, когда это может потребоваться: при выполнении длительного процесса, когда локальный объект более не требуется, но еще находится в области видимости. Однако, на современных JVM даже такого рода обнуления уже не требуются, поскольку JVM самостоятельно может обрабатывать такого рода случаи. void longProcess() { Object obj = new Object(); operationsWith(obj); obj = null; doSomethingElse(); // длительный процесс, и чтобы не держать в памяти obj, мы ранее ее принудительно обнулили. } Однако этот код может быть написан иначе: void longProcess() { { Object obj = new Object(); operationsWith(obj); } doSomethingElse(); // принудительное обнуление уже не требуется. } По поводу обнуления ссылки, если она является членом класса: по-моему такие поля нужно просто сделать локальными переменными и при необходимости передавать их в функции.

Ответ 5



Многие не понимают, что Java - это чистый pass-by-value. Поэтому ваш pref = null; Означает только то, что переменная pref не указывает на объект в памяти. Что там в действительности произойдет с этим объектом в памяти - зависит от многих факторов. Сама эта инструкция абсолютно бесмысленна и вы можете ее убрать. Если вы ее не можете убрать - у вас ошибка в другом месте.

Комментариев нет:

Отправить комментарий