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

时间:2012-03-12 22:54:03

标签: 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“free”,所以它无法解析~0.5mb的XML文件。

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

我的问题是:有没有办法加载这个XML而不会像这样崩溃应用程序?

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

这是一个未经修改的ROM,该模型的股票商业装置。

我可以正确地解析其他XML文件,甚至是这个XML文件,只要它们更小。例如,我在这个文件的190kb版本上取得了成功。

我已经读过SIGSEGV错误可能表示固件问题。不过,似乎很明显问题正在发生,因为它没有内存来解析大型XML,我想想办法完全绕过这个错误。

1 个答案:

答案 0 :(得分:2)

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

您执行的Bitmap处理是本机完成的,而不是Java代码,这样可以更好地进行内存管理,这就是为什么您不会遇到问题的原因。