【发布时间】:2012-07-05 14:48:39
【问题描述】:
我有一个例程每秒对 SQLite 数据库多次运行不同的查询。一段时间后我会得到错误
"android.database.CursorWindowAllocationException: - Cursor window allocation of 2048 kb failed. # Open Cursors = " 出现在 LogCat 中。
我记录了应用程序的内存使用情况,实际上,当使用量达到某个限制时,我收到了这个错误,暗示它用完了。我的直觉告诉我,每次我运行查询时,数据库引擎都会创建一个新缓冲区(CursorWindow),即使 .close() 游标,垃圾收集器和SQLiteDatabase.releaseMemory() 都不能足够快地释放内存。我认为解决方案可能在于“强制”数据库始终写入同一个缓冲区,而不是创建新缓冲区,但我一直无法找到这样做的方法。我已经尝试实例化我自己的 CursorWindow,并尝试将 SQLiteCursor 设置为它,但无济于事。
¿有什么想法吗?
编辑:来自@GrahamBorland 的示例代码请求:
public static CursorWindow cursorWindow = new CursorWindow("cursorWindow");
public static SQLiteCursor sqlCursor;
public static void getItemsVisibleArea(GeoPoint mapCenter, int latSpan, int lonSpan) {
query = "SELECT * FROM Items"; //would be more complex in real code
sqlCursor = (SQLiteCursor)db.rawQuery(query, null);
sqlCursor.setWindow(cursorWindow);
}
理想情况下,我希望能够在提供新查询之前.setWindow(),并在每次获得新数据时将数据放入相同的CursorWindow。
【问题讨论】:
-
我不知道是什么问题..:) 但我用来制作 SQLiteOpenHelper 类单例。所以我从来没有发现过这样的问题。
-
不,我不使用 SQLiteOpenHelper,我创建了一个包含 SQLiteDatabase 的静态 DataAccess 类。这很好用,我怀疑问题是否存在。这个问题更多地与 SQLite 库创建一个新容器来放置每个新查询的结果有关,而不是一遍又一遍地使用同一个容器。虽然我可以关闭游标,但 GC 清理的速度比创建新容器的速度慢,因此会产生内存占用。
-
您能否展示您的一些代码,尤其是您尝试设置自己的
CursorWindow时所做的事情? -
@GrahamBorland
public static CursorWindow cursorWindow = new CursorWindow("cursorWindow"); public static SQLiteCursor sqlCursor; public static void getItemsVisibleArea(GeoPoint mapCenter, int latSpan, int lonSpan) { query = "SELECT * FROM Items"; //would be more complex in real code sqlCursor = (SQLiteCursor)db.rawQuery(query, null); sqlCursor.setWindow(cursorWindow); }理想情况下,我希望能够在进行新查询之前设置 .setWindow,并在每次获得新数据时将数据放入同一个 CursorWindow 中。 -
将其编辑到您的问题中,不要将巨大的代码 sn-ps 粘贴为 cmets!
标签: android sqlite memory memory-leaks database-cursor