2012-09-25 63 views
16

我有一個內存問題,我找不出來。我有一個課程可以完成我所有的數據庫檢索工作。我的錯誤是:當我這樣做時分配光標時內存不足

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=733 (# cursors opened by this proc=733) 

內存分配錯誤的:

mDatabaseInterface.getGraphForLevel(level); 

我知道這是一個泄漏,因爲我粗略地調用這個方法每2.5秒,並且5或者6個第一個呼叫容易通過。現在,這裏是我DatabaseInterface類中的方法:

public Graph getGraphForLevel(Level level) { 

    //get the nodes 
    ArrayList<Node> nodes = new ArrayList<Node>(Arrays.asList(this.getNodesWithLevel(level))); 
    //get the edges 
    ArrayList<Edge> edges = new ArrayList<Edge>(Arrays.asList(this.getEdgesWithNodes(nodes))); 

    return new Graph(nodes, edges); 
} 

public Node[] getNodesWithLevel(Level level) { 

    List<Node> l = new ArrayList<Node>(); 

    Cursor cursor = mDatabase.query("nodes", null, 
      "level = " + wrapSql(String.valueOf(level.getId())), null, null, null, null); 

    while (cursor.moveToNext()) { 
     l.add(parseNodeFromCursor(cursor)); 
    } 

    cursor.close(); 

    return l.toArray(new Node[l.size()]);  
} 

private Node parseNodeFromCursor(Cursor cursor) { 

    Level l = getLevelWithId(cursor.getInt(2)); 

    return new Node(cursor.getInt(0), cursor.getString(1), l, 
      cursor.getInt(4), cursor.getInt(5)); 
} 

我有很多的相互調用的方法,但我知道,因爲這個類在另一個應用程序的工作原理它不是一個遞歸問題。我的主要問題是爲什麼不解開光標cursor.close()?如果我這樣做:

cursor = mDatabase.query(...); 
cursor.moveToNext(); 
Node node = new Node(cursor.getInt()); 
cursor.close(); 

遊標是否保留在那種情況下?

在此先感謝。

+0

只爲了解一個想法,節點和邊的表有多大? – Matthieu

+0

他們現在非常小,20行和10列最多 – chopchop

回答

27

如果在迭代過程中拋出異常,則調用cursor.close()應該位於finally塊中。

Cursor cursor = mDatabase.query("nodes", null, 
     "level = " + wrapSql(String.valueOf(level.getId())), null, null, null, null); 
try { 
    while (cursor.moveToNext()) { 
     l.add(parseNodeFromCursor(cursor)); 
    } 
} finally { 
    cursor.close(); 
} 
+0

感謝周圍終於解決了它 – chopchop

9

發生內存不足錯誤的原因之一是you are not closing your cursor

正如我所看到的,您打電話給cursor.close(),但是您應該調用此方法的正確位置,或者檢查是否應該在其他位置關閉它。

編輯:

如果你的活動是managing your Cursor,你可以考慮停止管理它,並關閉在方法的一切,並在onResume開放的一切行動和fillData一次。

+0

請參閱我的編輯 – Shrikant

+0

嗯謝謝我徹底檢查了我的代碼,並認爲我修復了它。但是它在跑完10分鐘後回來了(比10秒好很多!)。但是現在,而不是733左右的光標,它只會打開4個光標而崩潰。 android.database.CursorWindowAllocationException:光標窗口分配2048 kb失敗。 #打開遊標= 4(由此proc = 4打開的#遊標) – chopchop

+0

好吧。所以現在,如果你使用的是全局對象的遊標,首先嚐試清除遊標的內容,然後再次填充其中的數據,這樣遊標的內容不會超過閾值。 – Shrikant

相關問題