I am trying to debug an 'out of memory' error that I am experiencing, so to condense my example for the purpose of reaching out for help, I have a button, when clicked it queries the db and returns all the values into an ArrayList, the ArrayList is then used to populate a RecyclerView. This is successful, however if I press the button a second time, the 'out of memory' error occurs. The query returns a very large amount of data, and from the log I can see that with just 1 press of the button, not much memory is available (running on an emulator). I came to that conclusion from this line in the log:
com.wizzkidd.myapp D/dalvikvm: GC_FOR_ALLOC freed 1459K, 2% free 91444K/93016K, paused 40ms, total 40ms
and, as previously explained, the second press of the button gives this error:
com.wizzkidd.myapp E/dalvikvm-heap: Out of memory on a 152-byte allocation.
The error is pointing to my database helper class, more specifically, this section of code:
public List<MyInfo> getAllFromDb() {
List<MyInfo> myArrayList= new ArrayList<MyInfo>();
String selectQuery = "SELECT * FROM myTable";
SQLiteDatabase sqLiteDatabase = this.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery(selectQuery, null);
try {
if (cursor.moveToFirst()) {
do {
MyInfo myInfo = new MyInfo();
myInfo.setTitle(cursor.getString(0));
myInfo.setDescription(cursor.getString(1));
myArrayList.add(myInfo);
} while (cursor.moveToNext());
}
} catch (Exception e) {
Log.d(TAG, "Error while trying to get data from database");
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return tvGuideInfoList;
}
I have researched previous articles here on SO and the majority of answers say that the cursor must be closed in the finally block. But as you can see above, I am already doing this.
@antlersoft pointed me in the right direction, because I needed to clear/empty the data in my adapter that was used to fill my RecyclerView.
I came up with this quick method which allowed me to create a blank ArrayList, for MyViewAdapter which I then use it for the RecyclerView. I believe by filling the adapter with a blank ArrayList, it forced the Garbage Collection to clean up the previous data, thus allowing me to have a fresh pool of memory ready for the next fill.
private void clearRecyclerView() {
myViewAdapter = new MyViewAdapter(activity, new ArrayList());
myRecyclerView.setAdapter(myViewAdapter);
myViewAdapter.notifyDataSetChanged();
}