HPROF 之后我的应用程序中出现巨大的字节 []

2024-03-30

有时,特别是在我的应用程序中实现新功能时,我使用 DDMS + HPROF 来分析内存和堆使用情况。由于该应用程序似乎没有任何性能 ANR 问题,并且一切都运行顺利,最初我并不关心它 - 但现在,正如我看到的那样,它几乎总是相同的大小,我想知道它到底能做什么是。

每次我运行 HPROF 时,我都会检查泄密嫌疑人标签。总有一个android.graphics.Bitmap大约占用所有已用堆的 25% 的实例。

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

所以本质上有一个巨大的byte[]保留大量堆的实例,以及never被释放。根据this https://stackoverflow.com/a/12709604,我复制了它的值byte[],将其倾倒到.data文件,用 Gimp 打开,结果如下:

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

  • 我所有的图像文件大小都小于 8K
  • 其中只有一些是 PNG - 其余的我能够转换为 JPG,我做到了
  • 如果我添加更多图像,其大小无关紧要byte[]从应用程序一开始(4 个月前)就一直大致相同
  • 为了调试它,我尝试删除any图像文件来自drawable and drawable-xxx文件夹并在没有任何可绘制资源的情况下运行应用程序,并且byte[]还在那里
  • 我删除了几乎所有布局,只保留基本功能,结果相同
  • In the 支配树,根类是android.graphics.Bitmap

有谁知道这是什么byte[]我是否应该做点什么来释放它?

任何帮助表示赞赏!


只是为了澄清一些事情:

  • 应用程序中的图像/绘图在内存中以以下形式使用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 设备/模拟器上运行您的应用程序,并查看是否使用相同的内存。

作为另一个测试,您是否尝试过检查准系统应用程序上的内存使用情况(删除所有可绘制对象等)?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HPROF 之后我的应用程序中出现巨大的字节 [] 的相关文章

随机推荐