简短版:
经过一些调查,发现该消息是正常操作的一部分,不必担心。它被记录在“警告”级别,但我认为这只是过于积极了。
详细版:
这是一个明确标记为“窗口”游标,这意味着随着获得新记录,旧记录将被丢弃。在最简单的形式中,这样的“窗口”实现可能包含最多N行总计,可能带有一些预读取。 但在此实现中,窗口大小由总大小定义。内存中保存的行数基于可以适应整个窗口的数量,并且在运行时会发生变化(这可能更像是“缓冲”游标而不是“窗口”游标)。
作为具有(软-?)限制大小的缓冲实现,仅当缓冲区太满以容纳下一行时,才会丢弃最早的行。在这种情况下,会删除1个或更多旧的行。这个“保持分配行直到我们不能再容纳更多,然后释放我们缓冲区中最老的记录并重试”过程似乎是完全正常和预期的,这是保持内存空间受限的正常过程。
我基于在此处阅读源代码以及一些推理得出了这个结论:
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
这是 @vovahost 收到的消息:
CursorWindow: Window is full: requested allocation 2202504 bytes, free space 2076560 bytes, window size 2097152 bytes
第一种情况,请求的分配比窗口大小小得多。我预计类似的消息会重复发出,具有相同的窗口大小和不同的请求分配大小。每次打印这个时,从较大的窗口中释放内存,并进行新的分配。这是正常和健康的操作。
第二种情况,请求的分配大小超过了整个窗口大小。这是一个实际的问题,需要以更可流式化的方式存储和读取数据。
区别在于“长度”(总行数)与“宽度”(最大单行的内存成本)。前者(@tirrel的问题)不是问题,但后者(@vovahost的问题)是。