2011-06-01 63 views
2

我正在創建一個OutOfMemory異常,當一個非常大的JSONObject被創建但從未被Android框架垃圾回收時生成。在隨後的每次更新中,內存泄漏只會越來越大,直到內存不足。我們有一個隨時間變化的大數據結構,在每次更新時,我們將整個數據結構發送給客戶端並進行刷新。我知道這並不是最好的方式,但是改變整個基礎設施只需要移動設備需要花費一些時間和說服力。爲什麼Android的JSONObject保留在內存中?

至於在這裏和現在,當一個對象超出Java範圍,它應該被標記爲可用垃圾收集。我使用Eclipse MAT工具進行內存分析,根據該工具,從JSONObject解析出的每個字符串都有一個返回到原始JSONObject的鏈接。我有一個修復方法,我創建了一個remove函數,在該函數中,我遍歷每個JSONObjects鍵並在完成解析後調用JSONObject.remove(key),該函數的作用類似於魅力並收集所有內存。但是,爲什麼我需要這樣做呢?我不應該這樣做超出範圍對象。有任何想法嗎?

在此先感謝!

賈裏德·希恩

回答

2

也許這是最好的JSON響應轉換成一個POJO只要你收到它轉換。 傑克遜JSON解析器將在兩行代碼中爲您執行此操作,如果您需要這樣做,也可以將其重新轉換爲JSON對象。

傑克遜速度非常快(他們聲稱是所有解析器中速度最快的),所以你不會對性能造成太大影響。

在他們的網站上查看this教程。

從教程,你可以採取這種簡單的JSON對象:

{ 
    "name": 
    { 
     "first":"Joe", 
     "last":"Sixpack" 
    }, 
    "gender":"MALE", 
    "verified":false, 
    "userImage":"Rm9vYmFyIQ==" 
} 

,並解析與此代碼自己的對象:

ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally 
User user = mapper.readValue(new File("user.json"), User.class); 

只要你知道,我也有問題在我最近的Android項目中保留了內存,並最終放棄了使用JSON。

祝你好運!

+1

謝謝你的迴應。我實現了Jackson解析器,並且具有相同的內存保留問題,所以我想我會查看Android源代碼。果然,調用新的String(String string)不會在內存中創建一個新分配的String,它只會指向支持char []。公共字符串(String string){ value = string.value; offset = string.offset; count = string.count; } – 2011-06-03 17:08:10

+0

因此,有像你這樣的解決方法(新文件(「user.json」)))。我還發現,如果我遍歷JSONObjects鍵並調用JSONObject.remove(key),它實際上刪除了最後一個指向支持字符數組的指針。我發送了一封電子郵件給我們的谷歌代表關於該問題。 :-) – 2011-06-03 17:11:59

+1

剛剛意識到我在原始文章中提到了刪除(關鍵)解決方案。我重複自己的道歉。 – 2011-06-03 17:13:24