Android HPROF后我的应用程序中的大字节[]

Android HPROF后我的应用程序中的大字节[],android,memory-leaks,ddms,hprof,android-bitmap,Android,Memory Leaks,Ddms,Hprof,Android Bitmap,有时,特别是在我的应用程序中实现新功能时,我会使用DDMS+HPROF来分析内存和堆的使用情况。由于该应用程序似乎没有任何性能和恢复问题,而且一切工作都很顺利,起初我并不关心它——但现在,我看到它的大小几乎总是一样的,我想知道它到底是什么 每次运行HPROF时,我都会检查泄漏嫌疑犯选项卡。总是有一个android.graphics.Bitmap实例占据了所有使用堆的大约25% 我想进一步了解这是怎么回事,所以我打开了支配者树,看到了: 因此本质上有一个巨大的byte[]实例,它保留了大量堆,

有时,特别是在我的应用程序中实现新功能时,我会使用DDMS+HPROF来分析内存和堆的使用情况。由于该应用程序似乎没有任何性能和恢复问题,而且一切工作都很顺利,起初我并不关心它——但现在,我看到它的大小几乎总是一样的,我想知道它到底是什么

每次运行HPROF时,我都会检查泄漏嫌疑犯选项卡。总是有一个
android.graphics.Bitmap
实例占据了所有使用堆的大约25%

我想进一步了解这是怎么回事,所以我打开了支配者树,看到了:

因此本质上有一个巨大的
byte[]
实例,它保留了大量堆,而且永远不会释放。根据,我复制了
字节[]
的值,将其转储到一个
.data
文件中,用Gimp打开,结果如下:

所以基本上,它看起来像PNG图像的“alpha(0)”部分。考虑到以下事实:


  • 我所有的图像文件都只是为了澄清一些事情:

    • 应用程序中的图像/可绘制图像以
      android.graphics.Bitmap
      的形式在内存中使用
    • 从Android 3.0(API级别11)开始,像素数据与相关位图一起存储在Dalvik堆上。()
    • “大字节[]”可能言过其实,因为它的堆空间刚刚超过1MB
    泄漏嫌疑犯报告可能会有所帮助,但在本例中,考虑到其最大嫌疑犯的内存刚刚超过1MB,它并没有告诉您多少。现代设备提供64MB以上的堆

    让我们计算一下这个位图的内存需求。此位图占用堆上的1127584字节。如果我们假设此位图是使用ARGB_8888配置的,则每个像素使用4个字节,这意味着您的图像包含281896个像素(或大约530x530个像素)。这听起来对你所做的事情不合理吗

    也可以考虑Android在不同的“桶”中的使用方式:DMPI、HDPI、XHDPI等等。比如说,你在<>强> MdPI 桶中有一个200×200的图像,而你打开了一个在<强> XHDPI <强>设备上的应用程序。此图像将缩放为两倍大,设备分辨率为400x400。因此,虽然200x200映像可能不会占用太多堆空间(200x200x4=160kb),但400x400映像将需要相对较大的堆空间(400x400x4=640kb)。有关这方面的更多信息,请参见

    一个很好的工具,用于快速计算图像桶的差异:

    你说你拿走了一些拖带,但还剩下什么?您是否考虑过可能来自外部库的绘图

    回答你的最后一个问题:有人知道这个字节[]是什么,我是否应该做些什么来释放它

    我想说:堆中的这一小部分内存没有什么好担心的。如果它困扰着你,请密切关注它,确保它不会超出实际的范围。如果仍然怀疑内存泄漏,请在屏幕之间导航,观察堆是否继续增长。假设不缓存位图,则在两个屏幕之间来回导航时,堆应保持一致/可预测的大小

    作为补充说明,DDMS使动态监视堆大小变得非常容易。在准备潜水之前,无需进行HPROF转储。看看。请特别注意“Cause GC”按钮,因为需要它来触发初始堆大小的更新

    --更新--

    为了进一步回答这个问题,我有一个不受支持的怀疑,那就是应用程序的一些资产(系统资产/纹理?)被加载到了应用程序的内存空间中。请看幻灯片64:

    Android 4.4现在生成一个包含所有框架资产的单一纹理,由所有进程共享。这样可以在每个过程中节省一点内存,但也有助于批处理和合并图形操作,以自动优化应用程序

    这似乎意味着内存用于运行4.4之前版本的每个应用程序中的系统位图/绘图。如果是这样的话,我会质疑这个1MB是否就是那个空间。我想知道你是否可以在4.4设备/模拟器上运行你的应用程序,看看是否使用了相同的内存


    作为另一项测试,您是否尝试过在裸体应用程序上检查内存使用情况(删除所有可绘制文件等)?

    PNG和JPG的文件大小不可比较-Android内存中的位图是未压缩的大小(宽度*高度*色深)。@funkthemank是的,但删除了所有图像后仍保留着巨大的字符[…]。。。?我使用了相当数量的可绘制图像,但对我来说仍然很奇怪。首先,感谢您提供的详细答案。我意识到我可能夸大了“巨大”这个词,但目前它是我记忆中最大的对象,我并不担心它为什么会出现,它是由什么引起的。您所做的计算听起来很合理-到目前为止,我的图像中几乎90%都在xhdpi文件夹中,我还需要将其添加到其他文件夹中,因此我将在考虑您的答案的情况下对其进行一些额外的研究,如果合适,我将选择您的答案。谢谢最后我有时间尝试一下你在编辑中提出的建议,然后。。。对似乎是这样!我还没有一个运行Kit Kat的物理设备,但我配置了一个模拟器,让应用程序运行一段时间,看看堆,它就这样运行了,现在这个
    字节[]
    的使用空间大约是170KB!所以我想这是由这个引起的。我会做一些额外的测试,但分数归你,非常感谢你的帮助!