【问题标题】:Out of memory error: vast bitmap内存不足错误:巨大的位图
【发布时间】:2012-05-03 19:28:36
【问题描述】:

我的活动有列表视图,并且(除了所有其他东西)从网络加载图像并将它们显示在列表视图中。我可以使用 5 台安卓设备:2 台 HTC 欲望、LG P-350、另外一部手机和一台平板电脑。通常情况下,一切正常,但在 HTC 的愿望之一上启动时,应用程序往往会因 NullPointerException 而崩溃,这是由于内存不足错误(我猜是这样),这是输出:

05-03 14:41:23.818: E/dalvikvm(843): Out of memory: Heap Size=7367KB, Allocated=4991KB, Bitmap Size=16979KB

稍后,logcat 输出 nullpointerexception 的堆栈跟踪,其中我的一个静态变量突然变为空(该变量在应用程序的根活动中初始化,在整个应用程序中使用,并且肯定不会在代码中为空)。我想,由于内存不足,它被系统清空了。 据我了解,系统会尝试分配 17mb 的位图——我确信加载的图像不会那么大。它们是 100*70 jpeg,其中任何一个的重量都远小于 1mb。 我不明白的另一件事是为什么我只在一个设备上收到此错误 - 其他设备工作正常。

在我看来,这看起来很奇怪,我找不到任何线索,我需要建议。

【问题讨论】:

  • 1 图像大小小于 1MB,所以如果你添加所有图像大小,那么它就会大到足以给你 OutOfMemoryError。
  • 顺便说一句:没有系统会将您的变量归零。您的代码要么放置 null,要么变量尚未初始化。唯一可能发生这种情况的变量是那些明确为此而制定的变量:弱/软引用。
  • 我的列表视图的组织方式是,单击项目会启动一个新活动(让它成为活动 B)。我在 listview 的 onItemClick 中设置断点,在调试模式下运行应用程序,进入 listview 活动,按 listview 项目,在断点处停止,检查静态变量的值 - 它不为空。然后我在 B 的 onCreate 中放置断点,在那里执行停止,我检查相同的静态变量的值 - 它已经为空。是魔法吗?我在listview 项目单击侦听器和B 的oncreate 之间没有我的代码。变量在这两点之间的某处为空...
  • 2 Dharmendra:如果分配我所有的位图都会导致 OutOfMemoryError,为什么 logcat 会输出“Bitmap Size=16979KB”?不是说一个位图就这么大吗?

标签: android memory


【解决方案1】:

原因很简单:内存不是保存您的 JPG 数据,而是其解压缩后的等价物,不用说,它比源文件占用更多的 RAM 空间...请注意,这个 17 mb 的限制一次用于所有加载的位图,不一定是一个。

我不得不在我的一个程序(Mapquest Android API MapView 对象的自定义 Tile 加载器)中解决类似问题,最后我不得不尽可能调用位图的 recycle() 方法,以及使用System.gc()手动强制系统在战略位置进行垃圾收集...

很抱歉没有成为最好的消息的传递者......

您可能会使用与我相同的策略来解决您的问题:我基本上将加载的位图缓存在我的外部 SD 卡等硬盘中,并在需要时即时重新加载它们,而不是尝试将所有内容保存在 RAM 中。

【讨论】:

  • 如果崩溃是由于位图过大,在其他设备上怎么可能一切正常(其中一个是 HTC 的另一个愿望)?
  • 我认为没有针对所有 Android 设备固定的标准最大 RAM 占用空间大小。例如,我自己的运行 Android 2.1 的 HTC Desire 的最大占用空间约为 17 mb,但我的 Acer Iconia 平板电脑也需要更大的资源压力才能崩溃。任何人都可以通过一些官方文档确认这一点吗?注意:您的第二台 Desire 设备是否在完全相同的操作系统版本上运行?
  • 这是一个内核限制,例如 dalvik.vm.heapgrowthlimit 可以在 build.prop 中更改。在较旧的设备(或内存不足的设备)上,它被设置为 16 或 24Mb。在最近的设备上,它设置为 64Mb。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
相关资源
最近更新 更多