Execute Query
When you execute the Query series function in the Sqlitedatabase class , only the queries are constructed and the query is not executed.
(Source tracking path for query)
Execute Move (the Fillwindow inside is the place where the file handle is actually opened and the memory is allocated)
When you execute the cursor's move series function, the first execution creates a piece of shared memory for the query result set , which is Cursorwindow
Movetoposition Source Path
Fillwindow----really time-consuming place
The SQL statement is then executed to populate the shared memory with the data,
Fillwindow Source Path
In Sqlitecursor.java, you can see
1@Override2PublicBoolean OnMove (int Oldposition,Int newposition) { 3 // Make sure the row at Newposition is present in the Window 4 if (Mwindow = null | | Newposition < Mwindow.getstartposition () | | 5 newposition >= (mwindow.getstartposition () + Mwindow.getnumrows ())) { Fillwindow (newposition); Span style= "color: #008080;" > 7 } 8 9 return true;
If the location of the requested query is within the scope of Cursorwindow, Fillwindow will not be executed.
And beyond the range of Cursorwindow, Fillwindow is called,
And in the Nativeexecuteforcursorwindow,
When fetching a record, Cursorwindow is emptied if the location to be requested exceeds the window range:
1 Copyrowresult CPR =Copyrow (env, window, statement, NumColumns, Startpos, addedrows);2if (CPR = = Cpr_full && addedrows && startpos + addedrows <Requiredpos) {3//We filled the window before we got to the one row we really wanted.// Clear the window and Start filling it again from here. // todo:would be nicer If we could progressively replace earlier rows. 6 Window->clear (); 7 Window->setnumcolumns (NumColumns); 8 startpos += addedrows; ; 10 CPR = Copyrow (env, window, statement, NumColumns, Startpos, addedrows); 11}
Cursorwindow the emptying mechanism will affect the multithreading read (usually think not to read and write, SQLite concurrency is actually serial execution, but can be read concurrently, it is emphasized that multithreaded reading may also have problems), see later an article "ListView concurrent Read and write database."
Cursor
Close (explicit call to close () reason)
Tracking source to see close
1//Sqlitecursor23Super. Close ();4Synchronized (This) {5Mquery.close ();6Mdriver.cursorclosed ();7}8910//Abstractcursor1112PublicvoidClose () {mclosed =True;14Mcontentobservable.unregisterall ();15Ondeactivateorclose ();16}1718ProtectedvoidOndeactivateorclose () {19if (mselfobserver! =Null) {20Mcontentresolver.unregistercontentobserver (Mselfobserver);mselfobserverregistered =False;22}23Mdatasetobservable.notifyinvalidated ();24}252627//Abstractwindowedcursor2829/**@hide*/30@Override31ProtectedvoidOndeactivateorclose () {32Super. Ondeactivateorclose ();33CloseWindow ();34}3536ProtectedvoidCloseWindow () {37if (Mwindow! =Null) {38Mwindow.close ();Mwindow =Null;40}41}42434445//Sqliteclosable4647PublicvoidClose () {48Releasereference ();49}5051PublicvoidReleasereference () {52Boolean Refcountiszero =False;53SynchronizedThis) {Refcountiszero =--mreferencecount = = 0;55}56If(Refcountiszero) {57Onallreferencesreleased ();58}59}6061//Cursorwindow6263@Override64ProtectedvoidOnallreferencesreleased () {65Dispose ();66}6768Privatevoid Dispose () {69 if ( Mcloseguard! = null Mcloseguard.close () }72 if (mwindowptr! = 0) {73 74 Nativedispose (mwindowptr); ; }77}
View Code
In the path associated with Cursorwindow, the final call Nativedispose () empties Cursorwindow;
When the cursor is reclaimed by GC, Finalize is called:
1@Override2ProtectedvoidFinalize () {3Try{4//If the cursor hasn ' t been closed yet, close it first5if (Mwindow! =Null) {6if (mstacktrace! =Null) {7 String sql =Mquery.getsql ();8int len =Sql.length ();9Strictmode.onsqliteobjectleaked (Ten "finalizing a Cursor that have not been deactivated or closed." +One "database =" + Mquery.getdatabase (). Getlabel () +", table =" + medittable + +"," query = "+ sql.substring (0, (len > 1000)? : Len), mstacktrace); Close (); + } finally {+ Super. Finalize (); }
However, Finalize () did not release Cursorwindow, and Super.finalize (); It just untied the observer and didn't release Cursorwindow .
So not calling Cursor.close () will eventually cause the shared memory (1M or 2M) in the Cursorwindow to leak.
Http://www.cnblogs.com/hellocwh/p/4924732.html
From the source to see how SQLite in Android Read db (Turn)