2010-03-14 53 views
3

我一直在使用SAX解析器來獲取各種XML的數據,但是今天我用一個hudge XML來解決新問題(與以前的,這裏大約有12K條線),裏面有很多重複的項目。在大多數情況下,該項目是一個塊的一部分:在Android中使用SAX解析器 - OutOfMemory問題

<content> 

    <item lbl="blabla"> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    </item> 

    <item lbl="blabla"> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    <item lbl="blabla"/> 
    </item> 
</content> 

的布拉布拉部分是當然的變化......但是,我想,以保持項目的結構(它們是標題和副標題)。爲此,我附加每個blabla的開始和結束標記<itemx>blabla</itemx>,其中x是項目(1,2,3或4)樹中的位置。 有點問題的部分是,與此同時,我創建了成千上萬的無用對象,並且垃圾收集器沒有時間在解析器之後進行清理,並且不可避免的OutOfMemory出現在我的面前... 我不知道如何處理它;最好的方法是如果我可以把<content></content>的全部內容,但我不確定這是可能的SAX解析器。

任何幫助是值得歡迎的任何解決方案深深感謝...

回答

2

大部分情況下,您無法「快速創建對象以至於GC無法跟上」。事實上,當GC需要發生時,您的整個應用程序都會暫停,直到它完成,所以您無法領先於此。

唯一的例外是Bitmaps,它有點特別處理 - 即使它們的分配沒有發生,它們也會計入Java堆中。這很好,除非Bitmap的內存在其終結器運行之前不會被釋放,並且終結器做的與收集的垃圾分開運行,並且不會阻止應用程序。因此,創建一堆位圖並簡單地放開它們(不調用顯式釋放位圖內存的方法)確實會導致內存不足異常。

但是,如果你不分配(和放開)位圖對象,你還有其他一些問題,可能只是...沒有足夠的內存用於你的所有分配。您可以使用帽子工具(以及較少程度的DDMS中的簡單Java堆信息)來查看您分配的空間是多少。

3

如果你試圖讀取數據超出可用內存,那麼你就需要堅持的數據存儲釋放到繼續閱讀。

您是否考慮過在讀取數據時將數據存儲在sqlite database中?

您還應該避免創建大量無用的臨時對象,您是否可以通過突破單個對象或小對象池來避免垃圾堆放?

如果您正在尋找內存中的整個文檔樹,那麼您應該使用DOM解析器(DocumentBuilder適用於Android。)但是,如果您使用SAX解析器運行內存不足,很有可能DOM解析器也會耗盡,除非你的SAX事件正在製造和銷燬大量的對象實例。

+0

事實上,我正在將數據存儲在SQLite數據庫中,但僅在解析結束時... 同樣,是的,我創建了大量對象,因爲我試圖保留項目樹。 ..不幸的是,我看不到其他的選擇... 感謝您的回答,它證實了我的恐懼...... :) – Sephy 2010-03-14 22:15:38

+0

您可以隨時嘗試使用「DocumentBuilder」,因爲它意味着爲您保留整棵樹以通用的方式。 – 2010-03-14 22:30:28