Android 分配游标时内存不足
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12577400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Out of Memory when allocating cursors
提问by chopchop
I have a memory problem that I can't figure out. I have one class that does all my database retrieving work. The error I have is the following:
我有一个我无法弄清楚的记忆问题。我有一个类来完成我所有的数据库检索工作。我的错误如下:
android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=733 (# cursors opened by this proc=733)
The memory allocation error occurs when I do this:
执行此操作时发生内存分配错误:
mDatabaseInterface.getGraphForLevel(level);
I know it's a leak because I call this method every 2.5 seconds roughly, and the 5 or 6 first calls go through easily. Now here are the methods in my DatabaseInterface class:
我知道这是一个泄漏,因为我大约每 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));
}
I have a lot of methods that call each other but I know it's not a recursion problem because this class works in another app. My main question is why doesn't cursor.close()
liberate the cursor? If I do something like:
我有很多相互调用的方法,但我知道这不是递归问题,因为这个类在另一个应用程序中工作。我的主要问题是为什么不cursor.close()
释放光标?如果我做这样的事情:
cursor = mDatabase.query(...);
cursor.moveToNext();
Node node = new Node(cursor.getInt());
cursor.close();
Is the cursor retained in that case?
在这种情况下是否保留光标?
Thanks in advance.
提前致谢。
回答by Graham Borland
The call to cursor.close()
should be in a finally
block in case an exception is thrown while you're iterating over it.
调用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();
}
回答by Shrikant
One of the reasons for occurring Out of Memory error is you are not closing your cursor
.
发生内存不足错误的原因之一是you are not closing your cursor
。
As I can see, you are calling cursor.close()
, but is it the right place where you should call this method or check if you should close it on some other place.
正如我所看到的,您正在调用cursor.close()
,但它是否是您应该调用此方法或检查是否应该在其他地方关闭它的正确位置。
EDIT:
编辑:
If your activity is managing your Cursor
, you may consider stop managing it and closing everything in the onPause
method, and in onResume
open everything up and fillData once again.
如果您的活动是managing your Cursor
,您可以考虑停止管理它并关闭onPause
方法中的onResume
所有内容,并再次打开所有内容并填充数据。