2012-09-25 35 views
16

私にはわからないメモリの問題があります。私はすべてのデータベース検索作業を行う1つのクラスを持っています。私が持っているエラーは以下の通りです:私はこれを行うときカーソルを割り当てるときにメモリが不足する

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つの最初のコールが簡単に通過します。私はお互いを呼び出すが、このクラスが別のアプリで動作しますので、私はそれが再帰の問題ではないことを知っている方法の多くを持って

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)); 
} 

:今ここに私のDatabaseInterfaceクラスのメソッドです。私の主な質問は、なぜ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

メモリ不足エラーが発生する理由の1つは、you are not closing your cursorです。

私は、cursor.close()を呼び出していますが、このメソッドを呼び出すか、別の場所で閉じるべきかどうかを確認するのが適切な場所です。

EDIT:あなたの活動がmanaging your Cursorある場合

、あなたはそれを管理し、方法ですべてを閉じて停止、およびonResumeに再びすべてを開き、fillData検討することができます。

+0

私の編集 – Shrikant

+0

mmmを参照してください。私のコードを徹底的にチェックして、修正したと思っています。しかし、それは10分後に戻ってきた(10秒よりずっと良かった!)。しかし、今では733個のカーソルの代わりに、カーソルが4個だけ開いてクラッシュします。 android.database.CursorWindowAllocationException:2048 kbのカーソルウィンドウ割り当てに失敗しました。 #開いているカーソル= 4(このproc = 4で開かれたカーソルの数) – chopchop

+0

いいえ。カーソルのグローバル・オブジェクトを使用している場合は、まずカーソルの内容を消去してから、その中のデータを再度入力してください。カーソルの内容がしきい値を超えないようにしてください。 – Shrikant

関連する問題