Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
看起来不一致的OutOfMemory崩溃在不同的Android设备上_Android_Bitmap_Out Of Memory_Bitmapfactory - Fatal编程技术网

看起来不一致的OutOfMemory崩溃在不同的Android设备上

看起来不一致的OutOfMemory崩溃在不同的Android设备上,android,bitmap,out-of-memory,bitmapfactory,Android,Bitmap,Out Of Memory,Bitmapfactory,我正在制作一个游戏,它必须在开始时加载所有位图,因为在内置的游戏编辑器中,用户可以将任何精灵放入关卡。此外,关卡使用各种精灵,而不使用任何允许为每个关卡动态加载精灵组的系统 一段时间后,游戏中的png图像已经超过250张,总大小为3.5MB 游戏使用BitmapFactory.decodeStream加载大多数精灵(大约200个),而不设置任何选项,另外还有大约50个精灵在活动的xml布局中引用 当我在各种设备上测试时,游戏有时会耗尽内存,但我找不到模式,甚至无法决定我必须减少多少,例如减少图像

我正在制作一个游戏,它必须在开始时加载所有位图,因为在内置的游戏编辑器中,用户可以将任何精灵放入关卡。此外,关卡使用各种精灵,而不使用任何允许为每个关卡动态加载精灵组的系统

一段时间后,游戏中的png图像已经超过250张,总大小为3.5MB

游戏使用BitmapFactory.decodeStream加载大多数精灵(大约200个),而不设置任何选项,另外还有大约50个精灵在活动的xml布局中引用

当我在各种设备上测试时,游戏有时会耗尽内存,但我找不到模式,甚至无法决定我必须减少多少,例如减少图像的大小或数量

我开发的手机,HTC desire和Android 2.2 24MB虚拟机堆大小从未运行过

Android 2.2和40MB虚拟机堆大小的Dell Streak也不会运行OOM

Android 2.1和24MB虚拟机堆大小的Motorola Milestone成功加载了所有精灵,但在启动其中一项活动(开始菜单)时,却被ImageView中使用的最后几个图像卡住了。如果我把一些这样的图像视图注释掉,它会加载ok,但稍后可能会阻塞其他活动之一。它也不稳定,可能是因为碎片在不同的发射中发生的方式不同

HTC hero和我的好友2.2(不知道堆大小,是16MB吗?)也崩溃了

最令人困惑的是,摩托罗拉拥有24MB,与HTC desire一样。2.1实现内存管理的效率是否较低?(例如,导致更多的碎片?)或者所有摩托罗拉手机的内存管理都更糟糕?那为什么HTC英雄2.2会崩溃呢?有什么比HTC英雄更大的欲望

看起来OOM发生在老式手机上,但这是我迄今为止唯一知道的事情

如果OOM只发生在占市场份额5%的老式手机上,我可以通过收集故障报告并从支持的设备列表中排除所有故障,从支持的设备列表中排除2.1或更具体的列表。否则,我现在需要将所有图像按一定的比例缩小(例如1.6),这意味着要调整所有45个级别的大小,这需要花费数天的时间进行设计和测试,重新定位GUI元素等。即使在这之后,我仍然不确定,在哪些设备上,位图的总大小减少一个因子(例如2)就足以避免OOM

有什么建议吗? 我应该为BitmapFactory设置任何特定选项吗?顺便说一句,大多数图像都有透明的bg像素,据我所知,不允许使用565格式

我花了两天的时间浏览这里和其他地方,但仍然不知所措


谢谢。

我不得不处理您的问题的一个更简单的版本-我们有3个2Mpix层彼此重叠,这并不奇怪,有时会导致OOM

在我的例子中,我没有使用3个相互重叠的ImageView,而是始终将所有6个MPix都保留在内存中,而是手动混合了这些层,从而在任何时候最多将4个MPix保留在内存中(在“静止”时仅保留2个MPix,即应用程序中更改的层)

这是一个经典的时空权衡——牺牲效率(时间)来获得内存(空间)。它有点慢,因为在处理完每个位图后,必须
回收()
以确保释放内存

至于不一致的OOM,可能与垃圾收集有关。您可以假设垃圾收集器是不确定的,因此任何内存压力也会变得不确定(取决于GC上次启动的时间)

简短的总结是,你必须非常非常小心你的内存使用,没有办法*


*理论上,您可以使用NDK直接从操作系统分配内存,从而在Dalvik堆之外分配内存。这是一个巨大的黑客攻击,Dalvik和您的分配器之间的桥梁将相当丑陋。

首先,您需要找到到底是什么在使用您所有的内存。例如,也许你可以回收位图。

只是为了理解,其他开发人员如何避免OOM?我的意思是,如果你知道OOM会发生,你就试着制作尽可能小和尽可能少的位图。另一方面,为了更好的游戏,你需要尽可能多和更大的图像。什么样的设备可以决定何时“足够”添加新位图?你怎么能确定还有一台设备没有发生OOM?通过改变引擎加载位图的逻辑,部分解决了OOM问题。而不是在应用程序启动时加载所有精灵,现在只在关卡启动时加载所需的精灵。现在,至少游戏开始时摩托罗拉没有崩溃。然而,在浏览了一些应用程序之后,它仍然会在OOM中崩溃。将System.gc()放在每个活动中对super.onCreate()的每次调用之前,这似乎也有帮助。现在,摩托罗拉很少发生OOM崩溃。当然,这并不能确保在其他设备上它可以正常工作。