android - 在低端设备上读取大型 XML 时,getXml() 内存不足

标签 android xml

我有一个在 Android 2.2.2 上运行的应用程序,当尝试读取稍大(约 500kb)的 XML 文件时,它耗尽了内存。

XML 文件位于/res/xml,其读法如下(以简化方式):

XmlResourceParser xmlParser = getResources().getXml(R.xml.myxml);

这在大多数设备上都能完美运行(尽管需要几秒钟才能完成)。然而,我正在针对低端设备(华为 M835)进行测试,并且在尝试加载该设备时似乎内存不足......它永远不会完成该调用。

我得到的错误不是很有帮助 - 它只是一个大转储,没有正确的堆栈跟踪或任何东西。这是我执行上述行后的完整 logcat 响应:

DEBUG(1700): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
DEBUG(1700): Build fingerprint: 'Huawei/M835/hwm835/M835:2.2.2/HuaweiM835/C177B622:user/release-keys'
DEBUG(1700): pid: 2798, tid: 2798  >>> com.mypackage.MyApplication <<<
DEBUG(1700): signal 11 (SIGSEGV), fault addr 00000000
DEBUG(1700):  r0 46a95008  r1 00000000  r2 0011ce24  r3 00000018
DEBUG(1700):  r4 0013e8f0  r5 00000000  r6 a8125a48  r7 0011ce24
DEBUG(1700):  r8 beebc460  r9 4166ebc0  10 416ae1c0  fp 4166ebbc
DEBUG(1700):  ip 80000000  sp beebc3e8  lr a8119b8b  pc afd0f110  cpsr a0000010
DEBUG(1700):          #00  pc 0000f110  /system/lib/libc.so
DEBUG(1700):          #01  pc 00019b88  /system/lib/libutils.so
DEBUG(1700):          #02  pc 000459e6  /system/lib/libandroid_runtime.so
DEBUG(1700):          #03  pc 00011cb4  /system/lib/libdvm.so
DEBUG(1700):          #04  pc 0003c3d8  /system/lib/libdvm.so
DEBUG(1700):          #05  pc 00023cb4  /system/lib/libdvm.so
DEBUG(1700):          #06  pc 0001c244  /system/lib/libdvm.so
DEBUG(1700):          #07  pc 0005155a  /system/lib/libdvm.so
DEBUG(1700):          #08  pc 00058faa  /system/lib/libdvm.so
DEBUG(1700):          #09  pc 00016c78  /system/lib/libdvm.so
DEBUG(1700):          #10  pc 0001d35c  /system/lib/libdvm.so
DEBUG(1700):          #11  pc 0001c1f4  /system/lib/libdvm.so
DEBUG(1700):          #12  pc 000513c8  /system/lib/libdvm.so
DEBUG(1700):          #13  pc 0003ec58  /system/lib/libdvm.so
DEBUG(1700):          #14  pc 0002e908  /system/lib/libandroid_runtime.so
DEBUG(1700):          #15  pc 0002f7be  /system/lib/libandroid_runtime.so
DEBUG(1700):          #16  pc 00008c86  /system/bin/app_process
DEBUG(1700):          #17  pc 0000d362  /system/lib/libc.so
DEBUG(1700): code around pc:
DEBUG(1700): afd0f0f0 1a00002b e88d0fe0 e2603000 e213301c 
DEBUG(1700): afd0f100 0a00000a e1530002 8202301c e1b0ce03 
DEBUG(1700): afd0f110 28b100f0 48b10300 28a000f0 48a00300 
DEBUG(1700): afd0f120 e3130004 1491a004 1480a004 e0422003 
DEBUG(1700): afd0f130 e2522020 3a000008 e3c1c01f e28cc040 
DEBUG(1700): code around lr:
DEBUG(1700): a8119b68 2a006063 1c38d00e ee7cf7f5 28006160 
DEBUG(1700): a8119b78 200cd103 61204240 1c29e086 f7f51c3a 
DEBUG(1700): a8119b88 6965ee60 686a61a5 886b61e2 d8014293 
DEBUG(1700): a8119b98 d90a42ba 4a3f493e 18712005 686e18b2 
DEBUG(1700): a8119ba8 96009701 ee70f7f5 1c27e063 372418ab 
DEBUG(1700): stack:
DEBUG(1700):     beebc3a8  00000000  
DEBUG(1700):     beebc3ac  beebc3f8  [stack]
DEBUG(1700):     beebc3b0  00000000  
DEBUG(1700):     beebc3b4  afd103f0  /system/lib/libc.so
DEBUG(1700):     beebc3b8  00000003  
DEBUG(1700):     beebc3bc  afd41724  /system/lib/libc.so
DEBUG(1700):     beebc3c0  46a95008  
DEBUG(1700):     beebc3c4  c0000000  
DEBUG(1700):     beebc3c8  beebc460  [stack]
DEBUG(1700):     beebc3cc  4166ebc0  
DEBUG(1700):     beebc3d0  416ae1c0  /dev/ashmem/dalvik-LinearAlloc (deleted)
DEBUG(1700):     beebc3d4  afd0c741  /system/lib/libc.so
DEBUG(1700):     beebc3d8  00000000  
DEBUG(1700):     beebc3dc  afd103f0  /system/lib/libc.so
DEBUG(1700):     beebc3e0  df002777  
DEBUG(1700):     beebc3e4  e3a070ad  
DEBUG(1700): #00 beebc3e8  00000000  
DEBUG(1700):     beebc3ec  a8125a48  /system/lib/libutils.so
DEBUG(1700):     beebc3f0  0011ce24  [heap]
DEBUG(1700):     beebc3f4  beebc460  [stack]
DEBUG(1700):     beebc3f8  4166ebc0  
DEBUG(1700):     beebc3fc  416ae1c0  /dev/ashmem/dalvik-LinearAlloc (deleted)
DEBUG(1700):     beebc400  4166ebbc  
DEBUG(1700):     beebc404  46a95008  
DEBUG(1700):     beebc408  0013e8f0  [heap]
DEBUG(1700):     beebc40c  a8119b8b  /system/lib/libutils.so
DEBUG(1700): #01 beebc410  000a8b90  [heap]
DEBUG(1700):     beebc414  1fe0106c  
DEBUG(1700):     beebc418  00000001  
DEBUG(1700):     beebc41c  0013e248  [heap]
DEBUG(1700):     beebc420  ad3780f8  /system/lib/libandroid_runtime.so
DEBUG(1700):     beebc424  0000aaa0  [heap]
DEBUG(1700):     beebc428  0013e8f0  [heap]
DEBUG(1700):     beebc42c  0013e248  [heap]
DEBUG(1700):     beebc430  ad3780f8  /system/lib/libandroid_runtime.so
DEBUG(1700):     beebc434  0000aaa0  [heap]
DEBUG(1700):     beebc438  0013e8f0  [heap]
DEBUG(1700):     beebc43c  ad3459e9  /system/lib/libandroid_runtime.so
ActivityManager(124): Process com.mypackage.MyApplication (pid 2798) has died.

出现此问题似乎是因为该设备仅分配了 22mb (?) 堆大小。当读取 Runtime.getRuntime().maxMemory().totalMemory()freeMemory() 时,我得到 22mb、2mb 和0.5mb(分别)。因为显然只有 0.5mb 的“空闲”空间,所以它无法解析 ~0.5mb 的 XML 文件。

(在我的其他测试设备上进行测试时,我得到了 32mb、5mb 和 2mb。)

我的问题是:有什么方法可以加载此 XML 而不会导致应用程序崩溃?

顺便说一句,我对应用程序进行了一些内存密集型位图操作,但这不会引发任何错误...它仍然设法在 24mb 限制下运行。我很难理解为什么简单的 XML 解析会给我带来这么多麻烦。

这是未经修改的 ROM,该型号的库存商业安装。

我可以正确解析其他 XML 文件,甚至这个 XML 文件,只要它们较小。例如,我成功地使用了该文件的 190kb 版本。

我了解到 SIGSEGV 错误可能表明存在固件问题。不过,很明显问题正在发生,因为它没有内存来解析大型 XML,我想想办法完全避免这个错误。

最佳答案

您想要与 getXML() 一起使用的 XML 文件已预先解析(从而将其完全加载到内存中),因此在您的情况下,我建议将 XML 移动到 raw 文件夹,并使用 SAXParser 读取它,SAXParser 在读取时解析 xml(仅在内存中保留当前节点所需的量)。

您所做的位图处理是在 native 完成的,而不是在 Java 代码中完成的,这允许更好的内存管理,这就是为什么您不会遇到这些问题。

关于android - 在低端设备上读取大型 XML 时,getXml() 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9675956/

相关文章:

javascript - 使用 JavaScript 或 jQuery 创建区分大小写或 'camelCase' 的 XML 节点

c# - System.Type 到 XmlSchema 内置类型

android - TabHost 可以在 Android 的另一个元素中使用吗?

java - Android 回调监听器 - 从 SDK 中的 pojo 发送值到应用程序的 Activity

java - 无法获取经纬度android

java - Hibernate 和 JAXB 注释发生冲突

android - 异常线程 "main"org.openqa.selenium.remote.UnreachableBrowserException : Could not start a new session, 使用 appium 时

java - 处理来自 Throwable catch 的 NullPointerException 的最佳方法? (安卓)

android - 在Android中更改LinearLayout的背景

c#(更具体地说是 xna)如何通过 http 请求 xml 文件?不需要支持 xbox