2012-03-12 41 views
2

我有一個應用程序在Android 2.2.2上運行,並且在嘗試讀取較大(〜500kb)的XML文件時內存不足。在低端設備上讀取大型XML時,getXml()的內存不足

的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,我想要想辦法繞過這個錯誤。

+0

您是否必須使用XML,或者您是否有機會使用其他內容,例如。 JSON? – Rasive 2012-03-12 23:01:34

+0

此時更改文件架構/格式會產生問題,因爲此項目已經停止,並且XML是CMS生成的(這是一種邊緣案例)。 – zeh 2012-03-12 23:37:08

回答

2

要與getXML()使用預解析(因此加載它完全到內存中),所以你的情況我建議的XML移動到raw文件夾,並與SAXParser的,其解析閱讀它的XML文件它讀取它時的xml(只保留當前節點所需的內存)。

你所做的位圖處理是本地完成的,而不是Java代碼,它允許更好的內存管理,這就是爲什麼你沒有這些問題。

+0

您是否認爲有一種方法可以讀取/ res/xml中的XML,就像它是「原始」資源一樣?我嘗試過'getResources()。openRawResource(R.xml.myxml))'(在一些例子中見過),但它似乎不起作用。 – zeh 2012-03-13 13:08:42

+0

那麼,最後我只是把所有東西都移到/ res/raw。我想保持原樣,因爲這個應用程序已經出來,但它似乎運作良好,並且是一個穩定的更新。謝謝! – zeh 2012-03-13 17:48:44