Cursor window: window is full
Asked Answered
C

4

42

I've created a ListView populated by the data returned from a query.
It works, but in the LogCat I've got the message:

Cursor Window: Window is full: requested allocation 444 bytes, free space 363 bytes, window size 2097152 bytes

and it uses a couple of minutes for loading / visualizing the ListView.

My query returns about 3700 rows of String/Int/Double, each of which with 30 columns; no images or particular datatypes

What does this message exactly mean and how can I avoid it?
Can you improve performances by changing this Cursor Window?

Central answered 20/11, 2013 at 11:16 Comment(7)
Refer this: #11863524Carlisle
Thanks but i've already seen this question and i can't use a SD CardCentral
any updates on this one? I'm getting the same problem in certain circumstances on a list of strings.Teratoid
Yes, i've changed work :) Sorry, no updateCentral
@RichardLeMesurier how you fixed ? I hitting same problem tooSick
@Central how you fixed ? I hitting same problem tooSick
@JohnJoe no idea how or if I solved it - this was a long time ago. That said, nobody should be using ListView in 2021, so at the very least migrate your code to RecyclerView. Perhaps that will even solve the problem for you.Teratoid
G
23

From my experience this means that the query results are too large for the cursor's window and it requests more memory. Most times this request is honored, but on low end devices it could throw exceptions.

I don't know the specifics of the app in question but you referred to a ListView. A ListView cannot show 3700 rows at once and a endless list could help to load the data on demand

My advise is to break up the query into a multiple queries that return smaller results and close them before running the next query. After each successive query combine the results.

Generalization answered 8/7, 2014 at 9:38 Comment(5)
A ListView can show a cursor with more than 10 000 rows (based on my own experience). Thi issue is defently about memory, not row count.Ivelisseivens
@Ivelisseivens agree, that's the whole point of a ListView: to lazily load and render the rows based on what's visible on the screen.Canalize
BTW, now I see that @Generalization wrote "A ListView cannot show 3700 rows AT ONCE". Sounds confusing but actually 3700 Views attached to a Window seems to be extraordinary situation :)Ivelisseivens
This answer is misleading: in order to find out, if this log message indicates a real problem or not, you should compare values of currently "requested allocation" and the total "window size". More details - in the answer of @user1575326 below.Brocade
"A ListView cannot show 3700 rows at once"- ListView doesn't load all of the views into memory at once. That's the difference between a ListView and a LinearLayout in a ScrollView.Canalize
R
15

Short version:

After some investigation, it appears that this message is part of normal operation, and not a cause for concern. It is logged at the "Warning" level, but I think this is simply overeager.

Longer version:

This is (clearly labelled as) a "Windowed" cursor, which means that old records will be discarded as new records are obtained. In the simplest form, such a "window" implementation may contain up to N rows total, possibly with some read-ahead. In this implementation, however, the window size is defined instead by the total size. The number of rows kept in memory is instead based on how many would fit in the overall window, and will vary at runtime (This could perhaps be considered more of a "buffered" Cursor than "windowed" Cursor).

As a buffered implementation with a (soft-?)capped size, the earliest rows will be discarded only when the buffer is too full to accommodate the next row. In this case, 1 or more older rows are dropped. This "keep allocating rows as-needed until we can no longer have room for more, at which point we free up the oldest record(s) in our buffer and try again" process appears to be completely normal and expected, as a normal part of the process to keep the memory space confined.

I based this conclusion on reading the source here, combined with some inference: https://android.googlesource.com/platform/frameworks/base/+/master/libs/androidfw/CursorWindow.cpp

Why are people talking about images and other massive LOBs?

If the size of a single row is larger than the entire "window" (buffer), then this strategy breaks down and you have an actual problem.

This was the message @op was getting:

Cursor Window: Window is full: requested allocation 444 bytes, free space 363 bytes, window size 2097152 bytes

This was the message @vovahost was getting:

CursorWindow: Window is full: requested allocation 2202504 bytes, free space 2076560 bytes, window size 2097152 bytes

In the first case, requested allocation is much smaller than the windows size. I expect that similar messages are issued repeatedly, with the same window size and varying requested allocation sizes. Each time this is printed, memory is freed from the larger window, and new allocations are made. This is normal and healthy operation.

In the second case, requested allocation size exceeds the overall window size. This is an actual problem, requiring storing and reading data in a more streamable way.

The difference is "length" (total number of rows) vs "width" (memory cost of the largest single row). The former (@tirrel's issue) is not an issue, but the latter (@vovahost's issue) is.

Rumania answered 25/9, 2018 at 20:11 Comment(1)
Nice and thorough answer.Fishworm
K
8

I also got this problem. In my case I saved a 2.2 MB image in database. When loading the data from the database using Cursor.getBlob() I would see this message in the Log:

CursorWindow: Window is full: requested allocation 2202504 bytes, free space 2076560 bytes, window size 2097152 bytes

After I would get this message if I try to retrieve any data (String, number, etc) for successive rows it is returned as null without any errors. The solution was to remove the 2.2 MB blob. I don't know if it's possible to load bigger blobs from database in Android.

Karnak answered 8/10, 2017 at 23:45 Comment(0)
F
1

Also, note that changing the window has overhead of IPC.

So, if the cursor has large number of items and is used with a listview, fast navigation results in change of window and hence frequent IPCs. This might result in ANR if the system is loaded.

Forsyth answered 22/10, 2021 at 15:41 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Beniamino

© 2022 - 2024 — McMap. All rights reserved.