Android Database - Could not allocate CursorWindow - android

When I often go back and forward in my learning-app (everytime loading the question and answer) i will get this error:
01-01 15:27:36.803: E/CursorWindow(3820): Could not allocate CursorWindow '/data/data/*package-name*/databases/quiz.db' of size 2097152 due to error -12.
I can't say exactly when I get this error, only that when im often changing the content
Can anybody help me to understand what this error means, please
Thanks

According to this question and answers you should check if you handle your cursors correctly and if the amount of data you query is too big (check the 2048k limit)

Related

Window is full! Retrieving bitmap from SQLite database

I am trying to store and retrieve the image captured by device camera in SQLite Database as BLOB . I have no problem to do it, but when I retrieve images from DB I get an error, because of cursor, right?
W/CursorWindow: Window is full: requested allocation 707903 bytes, free space 680839 bytes, window size 2097152 bytes
After long time looking for solution I couldn't find it. I found only a lot of questions about the same issue without solid solution.
I can store URI of image , like it is discussed Android: Cursor Window is full. But then what happens if user deletes the image from Phone Memory/SD Card?
Also its not a good idea to ignore it, answered here https://stackoverflow.com/a/37035510/8258166.
So, what should I do?
Many thanks in advance!

Cursor window: window is full

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?
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.
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.
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.
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.

CursorWindow size need to grow

I am asking this question because some answers on StackOverflow are not the ones I am looking for.
My issue is that in early versions of Android like 2.3, the query is very slow and I get this message.
My Error Message
06:37:25.521: ERROR/CursorWindow(322): need to grow: mSize = 1048576, size = 45, freeSpace() = 43, numRows = 8928
07-12 06:37:25.521: ERROR/CursorWindow(322): not growing since there are already 8928 row(s), max size 1048576This message does not happen on Android 3.0+ for me I think, but it still takes a long time to do the query, so I am looking into using limits. It works almost flawlessly on Android 4.0+ though without limits. I am using SQLite FTS3 MATCH queries as well.
The reason I have 8928 rows is because I'm doing search suggestions and someone can input a "t" and get 8928 rows or something even larger, which freezes up Android 2.3 apparently. I cannot limit my search suggestion threshold because some results with only two characters may have 20 results or 20000+ depending on what it is.
Android SQLite and huge data sets This link is probably the best place for answers. The last answer in the given link seems promising, but there is no way to get the number of rows unless you do cursor.getCount(), which requires you to get the total number of rows from a big query (ex. 20000+ results), unless I'm thinking about it wrong. Is there some workaround to this? How would you do this in code to solve the CursorWindow problem?

GreenDao - determine database size on runtime

I would like to know please how to get my database(which is off course *.sqlite file) size in bytes?
My current way to do it(which isn't working) is:
new File(DataManager.getInstance().db.getPath()).length()
but I'm just getting here the same number every time 53,676~ , which is irrelevant to the database's content, I'm getting this number even when it's empty.
Thank you.
OK the solution is pretty simple, my recent way to check the database file was good.
But I didn't take in account that greenDao adds to the database another 53 KB. So an empty DB size would be 53± KB and after some insertions it would get bigger and bigger.

Android Lucene OutOfMemoryExceptoin

I have a Lucene Index with 50571 documents in it from 1740 books. I have two processes that create this index. The first process is to create the index on the device document by document. This process is very slow. The other process is to create a book index on the server, (The exact same way I create it on the device) and download and merge it with the master index. This one is much quicker to create the master index. Creating the index works fine either way.
The problem is when I search on the download-merge index I get an OutOfMemoryException, but when I search with the index that was created on the device I don't get that error. I went through and created the index book by book (download-merge) and searched after each book was indexed; based on that and when I get to book ~450 I start getting the OutOfMemoryException.
What is causing me to run out of memory.
Lucene is a memory hog. When writing "merging" indices together it stores the entire set of indices in memory twice. As quoted from the lucene documentation.
Note that this requires temporary free space in the Directory up to 2X
the sum of all input indexes (including the starting index).
If readers/searchers are open against the starting index, then temporary free
space required will be higher by the size of the starting index
That is a lot of memory. To mitigate this we have to shrink the size of the index by calling forceMerge(int) on the index writer. It is a slow process but it does shrink the size of the index. I am call this with an argument of 1 every time there is 50 or more files in the index directory.

Categories

Resources