2015-07-12 4 views
1

Я знаю, что если я подклассифицирую класс Handler в Android, лучше быть статичным или утечка памяти может произойти. например:Должен ли мой объект Handler быть статическим?

static class MyHandler extends Handler {...} 

Но что, если я просто создаю объект класса Handler? например:

Handler mHandler = new Handler(); 

Должно ли оно быть статическим? как это:

static Handler mHandler = new Handler(); 

Поскольку по умолчанию обработчик а будет использовать (основной) нить по умолчанию, и будет только один главный поток в процессе. Означает ли это, что mHandler не должен быть нестатическим полем в моем классе компонентов (т. Е. Activity, Receiver, ...)? Спасибо.

------------------ обновление --------------------- спасибо за ваш быстрый ответ. , но все следующие ответы - это не то, что я прошу.

проблема, Объект Handler «присоединяется» к процессу по умолчанию. (технически он прикрепляется к основной резьбе)

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

так, если я делаю это нестатическим полем деятельности, не так ли?

(мой вопрос более «теоретический/логический», а не «практический»)

+0

, и если у вас есть объект экземпляра, у вас есть проблема с ним? – Elltz

+0

см. Https://techblog.badoo.com/blog/2014/08/28/android-handler-memory-leaks и http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory- leak.html и многие другие ответы дяди Google – pskink

+0

@Elltz, да, они разные. Если mHandler не является статическим, он может быть уничтожен, если содержащийся класс (Activity, например) был уничтожен. Но если mHandler статичен, он не будет уничтожен, пока процесс не будет убит. Из-за вышеперечисленных различий они могут/должны обрабатывать различные задачи. – Henry

ответ

1

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

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

, например, если ваш обработчик находится в блоке кода, как в цикле во время или в функции или что-то,

{ 
    Handler testHandler = new Handler(); 
} 

когда этот блок заканчивается, testHandler уже не может быть достигнута. У него нет ссылки на него, и утилизация мусора будет обрабатывать его. Поэтому я не стал бы слишком беспокоиться об этом, кроме как бесконечный цикл, где каждая циклическая итерация способна создавать новый обработчик() в элементе array вне цикла, потому что тогда обработчики никогда не умирают и в конечном итоге вы используете всю свою память, а вы авария.

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

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

1

pskink указал на следующее (отлично) статьи в своем комментарии выше: http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html

Это ценная информация для Android разработчика (и фактически любого разработчика Java, как хорошо!): Внутренний класс, который не является static hold (неявная) ссылка на внешний класс (Activity). Поэтому в ситуациях, когда внутренний класс живет дольше, чем внешний класс, внешний класс не будет иметь права на сбор мусора до тех пор, пока не будет внутренний класс. Или, другими словами, это может привести к утечке памяти!

В Android, например, изменения конфигурации могут привести к разрушению объекта Activity и созданию нового. В таком случае, если обработчик (который был определен как внутренний нестатический класс) все еще работает - GC не сможет очистить объект Activity.

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

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

Смежные вопросы