Утечки памяти, единичный экземпляр

1

У меня есть несколько видов деятельности, где я показываю изображения с помощью этой библиотеки. Дело в том, что в приложении заканчивается память. Я попытался gc.clean(), нулевые ссылки, вызывать clear на объекте imageloader, но напрасно.

В MAT я обнаружил, что у меня есть несколько объектов одного и того же действия, и это поведение по умолчанию, если я не ошибаюсь. Я использовал singleInstance для подавления нескольких экземпляров, и это помогло с утечками памяти.

Прямо сейчас, из-за singleInstance, у меня проблемы с навигацией. Как вы думаете, я должен продолжить работу с singleInstance или попытаться исправить утечку памяти несколькими экземплярами?

Здесь ImageView gc корни инспекции: Изображение 174551

UPD:

 Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;

    ImageView imageView = (ImageView) convertView;
    if(convertView == null){
        imageView = new ImageView(_currentActivity);
    }

UPD2 (стратегии навигации):

У меня есть постоянный заголовок с кнопками, которые запускают домашнюю активность (с галереей) и активность профиля; во-вторых, есть подзаголовок, в котором также есть 3 кнопки, которые указывают на другие 3 действия со списками (состоящие из изображений + метки).

Эти элементы заголовка, подзаголовка доступны для каждого действия в приложении; Кнопки-ссылки ничего не делают:

startActivity(new Intent(getActivity(), MainActivity.class));

или

Intent activityIntent = new Intent(getActivity(), SomeActivityWithListViewInside.class);
// passing some data like list id
activityIntent.putExtra("list_id", listId);
startActivity(activityIntent);

Таким образом, эти экземпляры активности вызваны вызовами startActivity - как вы думаете, я должен играть с singleTop или любым другим параметром намерения, чтобы избежать этой проблемы?

  • 0
    Не могли бы вы показать свой код, где вы получаете изображения? Вы уверены, что не даете контекст активности при создании изображений? Это может быть вашей проблемой. Один экземпляр не создает утечек памяти.
  • 0
    Я передаю ссылку на активность в адаптере.
Теги:
android-layout

3 ответа

1
Лучший ответ

Вы не должны использовать singleInstance launchMode. Вам нужно, чтобы ваша навигация работала правильно, используя стандартный и/или singleTop launchMode. Если вы обнаружите, что у вас есть несколько экземпляров вашей активности, но вы этого не ожидали, значит, у вас что-то не так в вашей навигации. Наличие нескольких экземпляров ваших действий поддерживает все ваши взгляды и изображения вокруг и, вероятно, то, что вызывает проблемы с памятью.

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

РЕДАКТИРОВАТЬ: ответить на постер UPD:

Я не знаю, где вы устанавливаете _currentActivity, но это может быть вашей проблемой. Когда вы создаете представление внутри адаптера, вы всегда должны использовать контекст адаптера (который настроен, когда он был создан). Поэтому попробуйте следующее:

ImageView imageView = (ImageView) convertView;
if(convertView == null){
    imageView = new ImageView(getContext());
}

EDIT: ответьте на плакат UPD2:

Вам необходимо проверить свою навигацию, чтобы убедиться, что, когда пользователь выбирает одну из кнопок в заголовке или подзаголовке, у вас нет нескольких экземпляров ваших действий в стеке действий (если это не то, что вы хотите). Если в ваших действиях используется много пространства изображений (растровые изображения и т.д.), Вы должны убедиться, что у вас нет нескольких экземпляров. Вы можете переосмыслить свою навигацию или использовать комбинации singleTop, clearTop, reorderToFront и т.д., Чтобы не создавать экземпляры ваших действий, а просто переупорядочивать их в стеке действий, чтобы получить желаемое поведение навигации.

  • 0
    спасибо за предложения - я обновил свой вопрос. Пожалуйста, посмотрите на это.
3

я бы настоятельно рекомендовал не использовать странные флаги действий. У меня также всегда были проблемы с навигацией (и все еще есть, даже с фрагментами) с использованием API android.

вместо этого я предлагаю решить проблемы с памятью.

вы должны посмотреть это видео о утечках памяти и прочитать это о растровых изображениях.

Короче говоря, вот несколько советов:

  1. старайтесь избегать статических ссылок, особенно если они ссылаются на контекст.

  2. старайтесь избегать ссылок на контекст.

  3. если вы должны ссылаться на контекст, подумайте об использовании ApplicationContext.

  4. не забудьте закрыть потоки и диалоги при закрытии операции (при необходимости). попытайтесь закрыть службы, когда они больше не нужны.

  5. предпочитают статические внутренние классы над не статическими внутренними классами (поскольку они ссылаются на содержащийся класс).

  6. помните, что анонимные классы также имеют ссылку на содержащий класс.

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

  8. если возможно, попробуйте использовать softReference и/или weakReference для ссылки на "опасные" объекты, ссылающиеся на контекст.

  9. на API android API 10 и ниже, не забудьте переработать ваши растровые изображения. они обычно занимают много памяти.

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

  11. если вы используете какие-либо сторонние библиотеки или используете собственный код (например, с помощью NDK), не забудьте освободить его, когда это не понадобится. Далвик не поможет вам в этом.

0

Передача активности как контекста при создании представления не является хорошей: это предотвращает "освобождение" активности. Также вам может понадобиться масштабировать растровые изображения до требуемого размера.

  • 0
    Если представление является частью действия, необходимо передать действие как контекст, чтобы при уничтожении действия представление также очищалось. Если вы этого не сделаете, у вас будет утечка памяти.
  • 0
    Как я уже сказал, есть списки почти всех этих видов деятельности. Мне нужно их всплыть через адаптер. Итак, что касается вашего ответа - что я должен пройти при обновлении ImageView в getView адаптера? Контекст приложения?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню