Размер памяти кучи Android выглядит неправильно - PullRequest
1 голос
/ 20 января 2012

У меня есть приложение для Android, которое отображает множество изображений, оно работает, изображения собираются из URL, добавляются в очередь и собираются в 4 потока, сохраняются в кэше и затем отображаются в виде списка 4 изображения для строки На экране одновременно находится шесть строк. Всего 90 изображений.

Строки (и изображения) всегда перерабатываются, поэтому количество элементов всегда одинаково, и я ничего не инициализирую.

Кажется, это работает вполне нормально, у меня всегда средний размер кучи - 13 МБ.

У меня проблема в том, что в начале мой максимальный размер кучи довольно мал, и я получаю сообщения GC, такие как:

01-20 16: 48: 39.191: D / dalvikvm (9743): GC_FOR_ALLOC освобожден <1K, 31% свободен 12048K / 17351K, приостановлено 25 мс </p>

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

01-20 17: 02: 05.339: D / dalvikvm (11730): GC_FOR_ALLOC освобожден 544K, 72% свободен 13871K / 49159K, приостановлено 35 мс

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

Может кто-нибудь объяснить мне, что не так?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 20 января 2012

Для кэширования моих изображений я использую Map<String, Drawable> drawableMap.На OutOfMemoryError я вызываю эту функцию:

private void cacheLeeren()
{
    int size = drawableMap.size();
    int del = (int) (size * 0.3);
    Set<String> s = drawableMap.keySet();
    for (String t : s)
    {
        if (del >= 0)
        {
            drawableMap.put(t, null);
            del--;
        }
    }
}

Я думаю, что это не лучший способ ... но это работает; -)

0 голосов
/ 30 июля 2013

Я предполагаю, что ваше приложение в течение короткого времени достигает очень высокого пика использования памяти. Это правда, что в среднем вы используете только 13 МБ, но если ваша куча увеличивается до 50 МБ, это означает, что на мгновение вы потратили гораздо больше памяти, чем думаете.

Давайте попробуем выяснить, где это происходит. Вы упомянули, что используете кеш LRU. Этот кеш освобождает память, как только заполняется. Я предполагаю, что вы начинаете освобождать память слишком поздно, и эта память освобождается не сразу - это зависит от системы GC. Всякий раз, когда вы освобождаете некоторые элементы из кэша, попробуйте вызвать System.gc() вручную.

Вы также упомянули, что звоните Bitmap.recycle(). Насколько я знаю, это бесполезно на Android 3+, потому что собственная куча больше не используется для растровых изображений. Поскольку все растровые изображения находятся в куче dalvik, они будут освобождены GC. Вы не можете поспешить с этим, как раньше, если не вызовете System.GC() самостоятельно.

Другая идея для вашего источника проблем - фрагментация кучи. Смотрите мой предыдущий SO ответ на похожую проблему в этом вопросе .

0 голосов
/ 20 января 2012

Какую версию Android вы используете?Если вы тестируете на pre 3.0 (то есть 2.x), байтовые массивы, которые хранят большую часть информации в битовых картах, выделяются и хранятся в собственной памяти.Это означает, что в дампах кучи и в уведомлениях GC вы видите только небольшой объем памяти, используемый для указателей в растровых изображениях, а не фактический размер.

Для получения дополнительной информации ознакомьтесь с этой статьей Google IO по управлению памятьюи обнаружение утечек памяти: http://www.youtube.com/watch?v=_CruQY55HOk

Также я работал над несколькими приложениями, делающими подобные вещи.Я предполагаю, что либо размер вашего кеша слишком велик, либо (что более вероятно) изображения, которые вы отображаете и храните в кеше, намного больше того размера, который вы на самом деле хотите.Если вы отображаете растровое изображение в представлении изображения, оно будет сохранять исходное растровое изображение в памяти, даже если оно значительно больше, чем то, которое фактически помещается в представлении.Попробуйте изменить размеры изображений с диска, по крайней мере, ближе к соответствующему размеру, прежде чем пытаться их отобразить: Как масштабировать растровое растровое изображение на месте без предварительного чтения всего изображения?

...