分配游标时内存不足

cho*_*hop 16 memory sqlite android memory-leaks cursor

我有一个我无法弄清楚的记忆问题.我有一个类来完成我的所有数据库检索工作.我遇到的错误如下:

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

执行此操作时发生内存分配错误:

mDatabaseInterface.getGraphForLevel(level);
Run Code Online (Sandbox Code Playgroud)

我知道这是一个泄漏,因为我大约每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));
}
Run Code Online (Sandbox Code Playgroud)

我有很多方法相互调用,但我知道这不是递归问题,因为这个类在另一个应用程序中工作.我的主要问题是为什么不cursor.close()解放光标?如果我这样做:

cursor = mDatabase.query(...);
cursor.moveToNext();
Node node = new Node(cursor.getInt());
cursor.close();
Run Code Online (Sandbox Code Playgroud)

光标是否保留在那种情况下?

提前致谢.

Gra*_*and 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();
}
Run Code Online (Sandbox Code Playgroud)


Shr*_*ant 9

发生内存不足错误的原因之一是you are not closing your cursor.

我可以看到,你正在打电话cursor.close(),但是你应该调用这个方法或检查你是否应该在其他地方关闭它.

编辑:

如果您的活动是managing your Cursor,您可以考虑停止管理它并关闭onPause方法中的onResume所有内容,并打开所有内容并再次填充fillData.