只是为了澄清一些事情:
- 应用程序中的图像/绘图在内存中以以下形式使用
android.graphics.Bitmap
.
- 从 Android 3.0(API 级别 11)开始,像素数据与关联的位图一起存储在 Dalvik 堆上。 (管理位图内存 http://developer.android.com/training/displaying-bitmaps/manage-memory.html)
- “巨大的字节[]”可能有点夸张,因为它只是超过 1MB 的堆空间。
The 泄密嫌疑人报告可能会有所帮助,但在本例中,考虑到其最大的嫌疑对象只是超过 1MB 的内存,它并不能告诉您太多信息。现代设备提供 64MB 以上的堆。
让我们计算一下该位图的内存需求。该位图在堆上占用 1,127,584 字节。如果我们假设此位图是使用 ARGB_8888 配置的,则每个像素使用 4 个字节,这意味着您的图像包含 281,896 个像素(或大约 530x530)。这对于你正在做的事情来说听起来不合理吗?
另外,请考虑 Android 在可绘制对象的不同“存储桶”上进行缩放的方式:mdpi、hdpi、xhdpi 等。假设您有一个 200x200 的图像mdpi存储桶,并且您正在打开该应用程序xhdpi设备。该图像将缩放为两倍大,并且设备上的分辨率为 400x400。因此,虽然 200x200 图像可能不会占用太多堆空间(200 x 200 x 4 =160 kb),400x400 图像将需要相对较大量(4x)的堆空间(400 x 400 x 4 =640 kb)。有关这方面的更多信息,请参阅支持多屏 http://developer.android.com/guide/practices/screens_support.html#support.
一个很好的工具,可以快速计算图像存储桶的差异:Android DPI 计算器 http://coh.io/adpi/
你说你删除了一些可绘制的东西,但还剩下什么?您是否考虑过可能来自外部库的绘图?
回答你的最后一个问题:有人知道这个 byte[] 是什么吗?我是否应该做些什么来释放它?
我会说:堆上的这一小量内存无需担心。如果它困扰着你,请密切关注它并确保它不会超出看起来实际的范围。如果您仍然怀疑存在内存泄漏,请在屏幕之间导航并观察堆是否继续增长。假设您没有缓存位图,则在两个屏幕之间来回导航时,堆应该保持一致/可预测的大小
附带说明一下,DDMS 可以非常轻松地动态监控堆大小。在您准备好深入研究之前,不需要 HPROF 转储。看看使用DDMS http://developer.android.com/tools/debugging/ddms.html#heap。请特别注意“Cause GC”按钮,因为需要它来触发初始堆大小的更新。
-- UPDATE --
为了进一步回答这个问题,我的一个不受支持的怀疑是应用程序的某些资产(系统资产/纹理?)已加载到应用程序的内存空间中。请看此处的幻灯片 64:Android 4.4 的新增功能 http://www.slideshare.net/parisandroidug/whats-new-in-android-44-romain-guy-chet-haase.
Android 4.4 现在生成一个包含所有框架资源的单个纹理,并由所有进程共享。这可以在每个进程中节省一些内存,但也有助于批处理和合并绘图操作以自动优化应用程序。
这似乎意味着运行 4.4 之前版本的每个应用程序中的系统位图/绘图都使用内存。如果是这样的话,我会怀疑这1MB是不是那个空间。我想知道您是否可以在 4.4 设备/模拟器上运行您的应用程序,并查看是否使用相同的内存。
作为另一个测试,您是否尝试过检查准系统应用程序上的内存使用情况(删除所有可绘制对象等)?