我正在创建一个可以在jni端处理非常大的图像的应用程序。对于非常大的图像,我的意思是几乎所有可用的设备RAM都被分配到几个大块中。问题是在分配和释放所有这些内存后,相同的数量不再可用。
现在,你的第一个想法可能是这里显然存在内存泄漏!好吧,似乎没有。我使用
分析了我的内存使用情况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 :(得分:0)
事实证明,问题在于释放的内存显然必须进行垃圾收集。
虽然使用meminfo调用似乎暗示已释放所有内存,但该调用本身触发了垃圾回收。处理完成后,但在调用meminfo之前,该内存不可用。
我设法通过致电System.gc()
使一切正常。我知道不推荐这样做,据说这只是对系统的建议,但这确实可以解决问题。