Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid OutOfMemoryError with HashMap and ArrayList
    primarykey
    data
    text
    <p>I am parsing a csv file, more specifically a POI file, using opencsv and reading the info into an ArrayList. I need to cache the information in memory so when a user hits a button I check every POI and see if it is within the current bounds of the mapview. Some POI files can have 10K - 60K rows. I can read about 50K rows before my app force closes, so I set a limit of 30K to leave memory for other things. My issue is when I go to load another file I clear() the Arraylists I trimToSize() and I have tried declaring the ArrayLists as new ArrayLists but the GC never releases the old data from memory. I can clear() them and read a new file into them but something is not allowing the GC to free up the memory. I have no training in programming, IT, or CS. This is the first App I have ever worked on or written in Java / Android. I have worked, read and study for about 6 days now trying to figure out why I have this memory leak. Any help will be appreciated and any suggestion as to how I could optimize my code will also be appreciated as I am a complete noob. Also, the code below only shows the methods of concerning reading the file into memory. You can google opencsv to see the docs on how it works and if you need to see anything else let me know and I'll post it.</p> <p>Thanks in advance!</p> <pre><code> public class MainActivity extends MapActivity implements LocationListener { private static MapView mapView; int counter = 0; private ArrayList&lt;String&gt; arrLat = new ArrayList&lt;String&gt;(); private ArrayList&lt;String&gt; arrLong = new ArrayList&lt;String&gt;(); private ArrayList&lt;String&gt; arrName = new ArrayList&lt;String&gt;(); private ArrayList&lt;String&gt; arrInfo = new ArrayList&lt;String&gt;(); private ArrayList&lt;Boolean&gt; arrCheck = new ArrayList&lt;Boolean&gt;(); private ProgressDialog progressDialog; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // main.xml contains a MapView setContentView(R.layout.main); //Gets file name from ListOfFiles Activity Class Bundle extras = getIntent().getExtras(); if (extras != null) { boolean callreadPOIFile = extras.getBoolean("callreadPOIFile"); if(callreadPOIFile) { String filePath = extras.getString("filePath"); readPOIFileInThread(filePath); }else{ // Show user alert box } } } public void readPOIFileInThread(String filePath) { progressDialog = ProgressDialog.show(this, "", "LOADING:\n" + filePath + "\nPLEASE WAIT..."); final String finalFilePath = filePath; new Thread(new Runnable(){ public void run(){ try{ readPOIFile(finalFilePath); }catch(Exception e){ runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), "Exception, readPOIFileInThread", Toast.LENGTH_SHORT).show(); //progressDialog.dismiss(); } }); } progressDialog.dismiss(); } }).start(); } //Parse and load POI CSV File public void readPOIFile(String filePath){ arrLat.clear(); arrLong.clear(); arrName.clear(); arrInfo.clear(); arrCheck.clear(); arrLat.trimToSize(); arrLong.trimToSize(); arrName.trimToSize(); arrInfo.trimToSize(); arrCheck.trimToSize(); //arrLat = null; //arrLong = null; //arrName = null; //arrInfo = null; //arrCheck = null; //arrLat = new ArrayList&lt;String&gt;(); //arrLong = new ArrayList&lt;String&gt;(); //arrName = new ArrayList&lt;String&gt;(); //arrInfo = new ArrayList&lt;String&gt;(); //arrCheck = new ArrayList&lt;Boolean&gt;(); System.out.println(arrLat.isEmpty()); String lat = null; String lng = null; Double dLat; Double dLng; int lati; int lngi; String name = null; String info = null; CSVReader reader = null; //System.out.println(filePath); try { reader = new CSVReader(new FileReader(filePath)); } catch (FileNotFoundException e) { // prepare the alert box AlertDialog.Builder alertbox = new AlertDialog.Builder(this); // set the message to display alertbox.setMessage("There was an error reading file: " + filePath + "\n Please check the file format and try again."); // add a neutral button to the alert box and assign a click listener alertbox.setNeutralButton("Ok", new DialogInterface.OnClickListener() { // click listener on the alert box public void onClick(DialogInterface arg0, int arg1) { // the button was clicked //Toast.makeText(getApplicationContext(), "OK button clicked", Toast.LENGTH_SHORT).show(); } }); // show it alertbox.show(); e.printStackTrace(); } String [] nextLine = null; int count = 0; try { while ((nextLine = reader.readNext()) != null) { // nextLine[] is an array of values from the line //System.out.println(nextLine[0]+ "\n" + nextLine[1]+ "\n" + nextLine[2]+ "\n" + nextLine[3] + "\n"); try { lng = nextLine[0]; } catch (Exception e) { lng = Integer.toString(1); } try { lat = nextLine[1]; } catch (Exception e) { lat = Integer.toString(1); } try { name = nextLine[2]; } catch (Exception e) { name = "No Name..."; } try { info = nextLine[3]; } catch (Exception e) { info = "No Info..."; } //convert lat and long to double try{ dLat = Double.parseDouble(lat); dLng = Double.parseDouble(lng); }catch(Exception e){ System.out.println("error converting lat long to Double at row: " + count); break; } //convert lat lng to int lati = (int)(dLat * 1E6); lngi = (int)(dLng * 1E6); //add line to ArrayLists try{ arrLat.add(Integer.toString(lati)); arrLong.add(Integer.toString(lngi)); arrName.add(name); arrInfo.add(info); arrCheck.add(false); }catch (Exception e){ runOnUiThread(new Runnable() { public void run() { //Toast.makeText(getApplicationContext(), "Error reading. Please check the file. ", Toast.LENGTH_SHORT).show(); System.out.println("Error reading file."); } }); } count++; if(count == 10000 || count == 20000){ final int showcount = count; runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), showcount + " POI's loaded", Toast.LENGTH_LONG).show(); } }); } if(count == 30000) break; System.out.println(count); } final String toastFilePath = filePath; final int toastcount = count; runOnUiThread(new Runnable() { public void run() { if(toastcount &gt; 0){ Toast.makeText(getApplicationContext(), "File: " + toastFilePath + " read... \n" + toastcount + " point(s) were loaded...", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(getApplicationContext(), "INVALIDE FILE!\nFile: " + toastFilePath + " read... \n" + toastcount + " points.", Toast.LENGTH_LONG).show(); } } }); } catch (IOException e) { e.printStackTrace(); } } </code></pre> <p>FIXED:</p> <p>I finaly found my issue! After studying activity life cycles a I found that a new instance was being created every time I would go to my list activity to pick a file and cache it I was creating a new instance of my MainActivity. I set my MainActivity to singleTop mode in the manifest and moved some code the the onNewIntent() method and all is well. My app now works great!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload