Android - полностью очищает память, используемую jni

Я создаю приложение, которое обрабатывает очень большие изображения на стороне jni. И под очень большими изображениями я имею в виду, что почти все доступное ОЗУ устройств распределяется на несколько больших блоков. Проблема в том, что после выделения и освобождения всей этой памяти, тот же объем больше не доступен.

Теперь, ваша первая мысль, вероятно, о том, что здесь явно есть утечка памяти! Ну, похоже, нет. Я проанализировал использование памяти, используя

adb shell dumpsys meminfo (app package)

Вот мои результаты:
До обработки:

                 Pss  Private  Private  Swapped     Heap     Heap     Heap
               Total    Dirty    Clean    Dirty     Size    Alloc     Free
              ------   ------   ------   ------   ------   ------   ------
Native Heap    19736    19712       12     1268    36864    26663    10200
Dalvik Heap    15201    15176        0     3308    32992    16694    16298     

В течение:

                 Pss  Private  Private  Swapped     Heap     Heap     Heap
               Total    Dirty    Clean    Dirty     Size    Alloc     Free
              ------   ------   ------   ------   ------   ------   ------
Native Heap   889826   889804        8     1252   929792   914480    15311
Dalvik Heap    16769    16744        0     3308    33678    18541    15137            

После:

                 Pss  Private  Private  Swapped     Heap     Heap     Heap
               Total    Dirty    Clean    Dirty     Size    Alloc     Free
              ------   ------   ------   ------   ------   ------   ------
Native Heap    22234    22212        8     1252    45056    28468    16587
Dalvik Heap    16461    16436        0     3308    33871    17573    16298

До и после не совсем то же самое, но я также переключался между действиями, так что есть шум.

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

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

У кого-нибудь есть идеи получше?

0 ответов

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

Хотя использование вызова meminfo, казалось, означало, что вся память была освобождена, сам вызов запускал сборку мусора. После завершения обработки, но до вызова meminfo память была недоступна.

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

Другие вопросы по тегам