【发布时间】:2015-11-14 13:59:03
【问题描述】:
几天前,我们在 Play 商店中发布了一个应用程序,它处理高质量的位图,并且主要用于编辑它们。
当我们意识到 20% 的设备出现内存不足错误时,一切都很顺利。所以我们检查了我们的代码,发现 Android 没有释放用于在某些设备上存储位图数据的本机内存。在这种情况下,我们欢迎使用回收命令。
内存错误消失了(至少在高清设备中)。总之,我们很开心。但是今天我们开始看到 50% 的设备开始给出另一个错误:“无法复制回收的位图”
我们很沮丧。在我们的代码中的两行 bitmap.copy() 中,一半的设备无法同步执行这两行:
Bitmap anotherBitmap = bitmap.copy( bitmap.getConfig(), true );
bitmap.recycle();
所以我们取消了回收并发布了另一个更新,决定限制设备屏幕尺寸,所以小屏幕不会给我们差评。
这是我的问题。为什么有些设备在回收前可以复制,而一半不能?
我阅读了 Google 的位图相关文档,并且已经知道位图如何存储在 vm 的堆和本机堆上,垃圾收集如何处理内存不足错误等。Google 提供的用于加载和编辑大型位图的示例代码几乎相同和我们一样。
阅读了很多博客、google 组线程、github 代码示例...我想我仍然需要一本关于 Android 位图的好的文档/书籍。
PS:我们已经在使用 inSampleSize 在解码位图时对其进行缩放。
编辑 -- 以下是崩溃报告中的一些数据:
所有设备都是无根的。在大多数情况下,已用内存在 25% 到 35% 之间。
Manufacturers:
57% LG
31% Samsung
10% Casper Via V5 (Turkey based company, sells rebranded Chinese phones)
Devices:
81% LG D855 (G3)
18% LG D802TR (G2)
----
66% Samsung SM N910C (Galaxy Note 4)
20% Samsung SM A700F (Galaxy A7)
Operating Systems:
68% Android 5
31% Android 4
OS 5 Details
69% Android 5.0
30% Android 5.0.1
OS4 Details
66% Android 4.4.2
33% Android 4.4.4
【问题讨论】:
-
据我所知,如果将位图放置在本机内存中与您正在运行的 Android 版本有关,则更高版本的 Android 不会将它们存储在本机 ram 和您的内存中不需要调用回收。当谈到调用复制和回收时实际发生的情况取决于 oem 制造商和 android 版本,您能否提供更多有关设备和平台的信息?
-
一种可能的做法可能是仅在运行姜胡须或更早版本的手机上调用回收(如果您的手机出现问题的数据支持存在内存不足问题的手机都在运行的想法)姜饼或更早)。
-
至于关于位图的文档,最快和最简单的方法是检查 aosp 是如何做的,一些制造商确实改变了事情(三星是最大的罪魁祸首),但它应该为您提供足够的信息关于如何在大多数设备上完成的事情,易于搜索 aosp:androidxref.com
-
@JohanShogun 刚刚添加了崩溃报告详细信息以供检查。但据我所知,数据没有特定的设备或操作系统版本。一些带有 os 5 的 LG,一些带有 os 4 的 LG 崩溃了,但有些则没有。三星设备也是如此。 Jelly Bean (4.1) 是我们支持的最低版本,所以没有 Gingerbreads。