LINUX.ORG.RU

История изменений

Исправление Jefail, (текущая версия) :

Обычная ссылка в Java считается сильной. Это тебе тоже стоит изучить. Есть 4 типа: Strong, Weak, Soft, Phantom. Тип ссылки влияет на стратегию её сбора GC. В Android это особенно актуальная проблема.

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}
Вот, например здесь, внутри анонимного класса дергается глобальный филд mImageView. Предположим, что у тебя загрузка картинки из сети занимает секунд 15 (ну херовое у нас соединение, что поделать). Если за это время ты пару раз повернешь телефон - у тебя старое активити уничтожится и создастся новое (man activity lifecycle). Однако, из-за того, что анонимный класс держит неявную сильную ссылку на внешний класс и из него дергает ImageView, GC её не соберет и будет утечка памяти. Причем утечка будет иерархическая, потому что один сраный ImageView по цепочке потащит за собой всё, активити, контекст и так далее. Вариантов решения данной проблемы несколько. Но советую для начала действительно понять, что происходит под капотом и почему оно протекает.
https://www.youtube.com/watch?v=BkbHeFHn8JY

Исходная версия Jefail, :

Обычная ссылка в Java считается сильной. Это тебе тоже стоит изучить. Есть 4 типа: Strong, Weak, Soft, Phantom. Тип ссылки влияет на стратегию её сбора GC. В Android это особенно актуальная проблема.

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}
Вот, например здесь, внутри анонимного класса дергается глобальный филд mImageView. Предположим, что у тебя загрузка картинки из сети занимает секунд 15 (ну херовое у нас соединение, что поделать). Если за это время ты пару раз повернешь телефон - у тебя старое активити уничтожится и создастся новое (man activity lifecycle). Однако, из-за того, что другой поток оперирует сильной ссылкой на ImageView GC её не соберет и будет утечка памяти. Вариантов решения данной проблемы несколько. Но советую для начала действительно понять, что происходит под капотом и почему оно протекает.
https://www.youtube.com/watch?v=BkbHeFHn8JY