2048 kb 的 SQLite Android 数据库游标窗口分配失败 [英] SQLite Android Database Cursor window allocation of 2048 kb failed

查看:21
本文介绍了2048 kb 的 SQLite Android 数据库游标窗口分配失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个例程,每秒多次对 SQLite 数据库运行不同的查询.过了一会儿我会得到错误

I have a routine that runs different queries against an SQLite database many times per second. After a while I would get the error

"android.database.CursorWindowAllocationException: - 2048 kb 的光标窗口分配失败.# Open Cursors = " 出现在 LogCat 中.

"android.database.CursorWindowAllocationException: - Cursor window allocation of 2048 kb failed. # Open Cursors = " appear in LogCat.

我有应用程序日志内存使用情况,实际上当使用量达到某个限制时,我会收到此错误,这意味着它已用完.我的直觉告诉我,每次运行查询时,数据库引擎都会创建一个新的缓冲区 (CursorWindow),即使 .close() 游标,垃圾收集器和 SQLiteDatabase.releaseMemory()在释放内存方面足够快.我认为解决方案可能在于强迫"数据库总是写入同一个缓冲区,而不是创建新的缓冲区,但我一直无法找到一种方法来做到这一点.我尝试实例化我自己的 CursorWindow,并尝试将 SQLiteCursor 设置为它,但无济于事.

I had the app log memory usage, and indeed when usage reaches a certain limit the I get this error, implying it runs out. My intuition tells me that the database engine is creating a NEW buffer (CursorWindow) every time I run a query, and even though .close() the cursors, neither the garbage collector nor SQLiteDatabase.releaseMemory() are quick enough at freeing memory. I think the solution may lie in "forcing" the database to always write into the same buffer, and not create new ones, but I have been unable to find a way to do this. I have tried instantiating my own CursorWindow, and tried setting SQLiteCursor to it, but to no avail.

¿有什么想法吗?

来自@GrahamBorland 的示例代码请求:

re example code request from @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.

Ideally I would like to be able to .setWindow() before giving a new query, and have the data put into the same CursorWindow everytime I get new data.

推荐答案

此错误的最常见原因是未关闭的游标.确保在使用后关闭所有游标(即使出现错误).

Most often the cause for this error are non closed cursors. Make sure you close all cursors after using them (even in the case of an error).

Cursor cursor = null;
try {
    cursor = db.query(...
    // do some work with the cursor here.
} finally {
    // this gets called even if there is an exception somewhere above
    if(cursor != null)
        cursor.close();
}

要使您的应用程序在未关闭光标时崩溃,您可以启用 在您的应用程序中使用 detectLeakedSqlLiteObjects 的严格模式 onCreate:

To make your App crash when you are not closing a cursor you can enable Strict Mode with detectLeakedSqlLiteObjects in your Applications onCreate:

StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
   .detectLeakedClosableObjects()
   .detectLeakedSqlLiteObjects()
   .penaltyDeath()
   .penaltyLog()
   .build();
StrictMode.setVmPolicy(policy);

显然,您只会为调试版本启用此功能.

Obviously you would only enable this for debug builds.

这篇关于2048 kb 的 SQLite Android 数据库游标窗口分配失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆