分配游标时内存不足

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

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 nodes = new ArrayList(Arrays.asList(this.getNodesWithLevel(level))); //get the edges ArrayList edges = new ArrayList(Arrays.asList(this.getEdgesWithNodes(nodes))); return new Graph(nodes, edges); } public Node[] getNodesWithLevel(Level level) { List l = new ArrayList(); 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(); 

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

提前致谢。

  • 由于java.lang.IllegalArgumentException,应用程序因启动而崩溃:列'_id'不存在
  • 无法恢复活动错误
  • 使用游标加载器进行排球或服务
  • 如何检查游标是否为空?
  • Android eclipse startManagingCursor已弃用但想支持较旧的API版本?
  • setNotificationUri的机制是什么?
  • 方法调用可能会产生java NullpointerException
  • SimpleCursorAdapter,包含Android中的部分
  • cursor.close()的调用应该在finally块中,以防在您迭代它时抛出exception。

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

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

    正如我所看到的,您正在调用cursor.close() ,但它是否应该调用此方法或检查是否应该在其他位置关闭它。

    编辑:

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