nKn*_*nKn 8 android memory-leaks hprof ddms android-bitmap
有时,特别是在我的应用程序中实现新功能时,我使用DDMS + HPROF来分析内存和堆使用.由于应用程序似乎没有任何性能 - ANR问题,一切顺利,最初我并不关心它 - 但现在,因为我看到它几乎总是相同的大小,我想知道该死的是什么是.
每次运行HPROF时,都会检查Leak suspects选项卡.总有一个android.graphics.Bitmap实例占用了所有已用堆的大约25%.

我想进一步了解那是什么,所以我打开了支配树,看到了这个:

所以基本上有一个巨大的byte[]实例保留了大量的堆,并且从未被释放.根据这个,我复制了byte[]它的值,将它转储到一个.data文件中,用Gimp打开,结果如下:

所以基本上,它看起来像PNG图像的"alpha(0)"部分.考虑以下事实:
byte[]始终与应用程序的开始大致相同(4个月前)drawabledrawable-xxxbyte[]android.graphics.Bitmap任何人都知道它是什么byte[]以及我是否应该做任何事情来解放它?
任何帮助赞赏!
只是为了澄清一些事情:
android.graphics.Bitmap.该泄漏嫌疑人报告可能有用,但在这种情况下,它是不会告诉你太多考虑它的最大嫌疑人是刚刚超过1MB的内存.现代设备提供64MB +堆.
我们来计算这个位图的内存要求.该位图在堆上占用1,127,584个字节.如果我们假设使用ARGB_8888配置此位图,则每个像素使用4个字节,这意味着您的图像包含281,896个像素(或大约530x530).这对你正在做的事情听起来不合理吗?
此外,考虑Android在不同的"桶"中缩放的方式:mdpi,hdpi,xhdpi等.假设您在mdpi存储桶中有200x200图像,并且您正在xhdpi设备上打开应用程序.此图像将缩放为两倍大,并具有400x400的设备分辨率.因此,虽然200x200图像可能不会占用太多堆空间(200 x 200 x 4 = 160 kb),但400x400图像将需要相对较大量(4x)的堆空间(400 x 400 x 4 = 640 kb).有关此内容的更多信息,请参阅支持多个屏幕.
一个很好的工具,用于快速计算与图像存储桶的差异:Android DPI计算器
你说你删除了一些可绘制的东西,但还剩下什么?您是否考虑过可能来自外部图书馆的可绘制内容?
回答你的最后一个问题:任何人都知道这个字节是什么[]以及我是否应该做任何事情来解放它?
我会说:你的堆上的这么少的内存是没有什么可担心的.如果它困扰你,请密切关注它并确保它不会超出实际可行的范围.如果您仍然怀疑内存泄漏,请在屏幕之间导航并观察堆是否继续增长.假设您没有缓存位图,在两个屏幕之间来回导航时,堆应保持一致/可预测的大小
作为旁注,DDMS使得即时监控堆大小变得非常容易.在您准备好潜入之前不需要HPROF转储.请查看使用DDMS.请特别注意"原因GC"按钮,因为需要触发初始堆大小的更新.
- 更新 -
为了进一步回答这个问题,我有一个不受支持的怀疑是应用程序的某些资产(系统资产/纹理?)被加载到应用程序的内存空间中.请看这里的幻灯片64:Android 4.4中的新功能.
Android 4.4现在生成一个包含所有框架资产的纹理,由所有进程共享.这样可以在每个进程中节省一些内存,但它还有助于批处理和合并绘图操作以自动优化应用程序.
这似乎意味着内存用于运行4.4之前版本的每个应用程序中的系统位图/ drawable.如果是这种情况,我会质疑这个1MB是否是那个空间.我想知道你是否可以在4.4设备/模拟器上运行你的应用程序,看看是否使用了相同的内存.
作为另一个测试,您是否尝试检查准系统应用程序上的内存使用情况(删除所有可绘制的内容等)?