光标窗口:窗口已满

Tir*_*rel 31 database android cursor android-listview

我已经创建了一个ListView,它由查询返回的数据填充.
它有效,但在LogCat中我收到了消息:

Cursor Window: Window is full: requested allocation 444 bytes, free space 363 bytes, window size 2097152 bytes
Run Code Online (Sandbox Code Playgroud)

它使用几分钟来加载/可视化ListView.

我的查询返回大约3700行String/Int/Double,每行包含30列; 没有图像或特定数据类型

这条消息究竟意味着什么,我该如何避免呢?
您可以通过更改此光标窗口来提高性能吗?

Del*_*nco 17

根据我的经验,这意味着查询结果对于游标窗口而言太大,并且它会请求更多内存.大多数情况下,此请求很受欢迎,但在低端设备上,它可能会抛出异常.

我不知道有问题的应用程序的细节,但你提到了ListView.ListView不能同时显示3700行,无限列表可以帮助按需加载数据

我的建议是将查询分解为多个查询,这些查询返回较小的结果并在运行下一个查询之前关闭它们.在每个连续查询结合后结果.


vov*_*ost 8

我也遇到这个问题。就我而言,我在数据库中保存了 2.2 MB 的图像。使用从数据库加载数据时,Cursor.getBlob()我会在日志中看到以下消息:

CursorWindow: Window is full: requested allocation 2202504 bytes, free space 2076560 bytes, window size 2097152 bytes
Run Code Online (Sandbox Code Playgroud)

在我收到此消息后,如果我尝试检索连续行的任何数据(字符串、数字等),它将返回为,没有任何错误。解决方案是删除 2.2 MB 的 blob。我不知道是否可以从 Android 数据库中加载更大的 blob。


use*_*326 5

精简版:

经过一番调查后,看来此消息是正常操作的一部分,并不是引起关注的原因.它记录在"警告"级别,但我认为这只是过度的操作.

更长的版本:

这是(明确标记为)"窗口"光标,这意味着旧记录将在获得新记录时被丢弃.在最简单的形式中,这样的"窗口"实现可以包含总共多达N行,可能具有一些预读.然而,在该实现中,窗口大小由总大小来定义.保留在内存中的行数取决于整个窗口中适合的行数,并且在运行时会有所不同(这可能更多地被视为"缓冲"光标而不是"窗口"光标).

作为具有(soft - ?)上限大小的缓冲实现,只有当缓冲区太满而无法容纳下一行时,才会丢弃最早的行.在这种情况下,丢弃一个或多个较旧的行.这"根据需要继续分配行,直到我们不再有更多的空间,此时我们释放缓冲区中最旧的记录并再次尝试"过程似乎是完全正常和预期的,作为正常部分保持内存空间受限的过程

我在这里阅读源代码时得出了这个结论,并结合了一些推论:https: //android.googlesource.com/platform/frameworks/base/+/master/libs/androidfw/CursorWindow.cpp

人们为什么要谈论图像和其他大量LOB?

如果单行的大小大于整个"窗口"(缓冲区),则此策略会中断并且您遇到实际问题.

这是@op得到的消息:

Cursor Window: Window is full: requested allocation 444 bytes, free space 363 bytes, window size 2097152 bytes
Run Code Online (Sandbox Code Playgroud)

这是@vovahost得到的消息:

CursorWindow: Window is full: requested allocation 2202504 bytes, free space 2076560 bytes, window size 2097152 bytes
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,请求的分配比窗口大小小得多.我希望重复发出类似的消息,具有相同的窗口大小和不同的请求分配大小.每次打印时,都会从较大的窗口中释放内存,并进行新的分配.这是正常和健康的运作.

在第二种情况下,请求的分配大小超过了整个窗口大小.这是一个实际问题,需要以更流畅的方式存储和读取数据.

差异是"长度"(总行数)与"宽度"(最大单行的内存成本).前者(@ tirrel的问题)不是问题,但后者(@ vovahost的问题)是.