5

I was getting OutOfMemoryError messages in LogCat and my app was crashing because the errors were uncaught.

Two things were causing the OutOfMemoryError:
1. Reading a large text file into a string.
2. Sending that string to my TextView.

Simply adding a catch to these two things not only catches the OutOfMemoryError but appears to completely solve the out-of-memory problem.
No more crashing and no more error messages in LogCat. The app just runs perfectly.

How is this possible? What exactly is happening?


With this code, I was getting the error messages & app crashing:

try
{
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next();
} 
catch (FileNotFoundException e) 
{
e.printStackTrace();
}


myTextView.setText(myString);



Just by 'catching' the OutOfMemoryError, no more error messages in LogCat and no crashing:

try
{
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next();
} 
catch (FileNotFoundException e) 
{
e.printStackTrace();
}
catch(OutOfMemoryError e)
{
}


try 
{
myTextView.setText(myString);
} 
catch(OutOfMemoryError e)
{
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Eric Glass
  • 141
  • 3
  • 12

3 Answers3

2

I guess your string isn't loaded completely, or even if it is (it may throw the error just after adding the text), what happens depends on the current memory available for your app so catching OutOfMemoryError isn't a viable solution here.

If you really want to load a large string file and display it in an EditText, I recommend you to load only a small part of the file (let's say 50kB), and implement some kind of paging, like a button which loads the next 50kB. You can also load additional lines as the user scrolls through the EditText.

Dalmas
  • 26,409
  • 9
  • 67
  • 80
1

If you catch the OutOfMemoryError, the garbage collector tries to free up the memory previously used and thus the application can carry on if the application will let the garbage collector do its job (i.e. the application has no longer a reference to that large string of yours).

However, catching an OutOfMemoryError is far from fool-proof. See Catching java.lang.OutOfMemoryError?.

Community
  • 1
  • 1
Tom
  • 3,913
  • 19
  • 28
1

When you catch the exception the JVM tries to recover from it by calling the Garbage Collector and scraping the objects that are not used anymore.

This might solve the problem in your case. But imagine that the problem appears because of bad coding and memory leaks all over your code. Catching will not solve the problem because GC will not collect any objects. GC will kick in more frequently and the performance of your application will drop until it becomes unusable.

Basically, this error happens when the JVM cannot allocate more memory on heap for new objects. Catching the exception and letting the GC to clean up and release memory might be a solution but you are never absolutely sure that you are in recoverable state. I would use the catch block to recover from the error, log it and close the application. If you want to solve the memory problem in this case, do it properly and initialize the JVM with more memory (using the java argument -Xmx)

darijan
  • 9,725
  • 25
  • 38
  • I'm having the exception in an image reflection method. Can I catch the error if it happens, stop the processing, clean up the objects and simply use the original image? – frostymarvelous Aug 30 '14 at 14:15
  • It is really considered a bad practice to catch an exception like that. A better practice would be to avoid that exception from happening by 1) trying to find where your code leaks, 2) increasing memory given to the JVM when the program starts (with -Xmx). Also, I am not sure what do you mean by "image reflection method", can you explain that a bit? – darijan Aug 31 '14 at 21:33
  • Basically, I create a new image from an existing one that reflects the image. Sorry, I guess that comes across as Reflection. Anyway, the code is not leaking. I get the error sometimes when creating a new image with Bitmap.createBitmap. If all fails, I will have to use subsampling I guess, but the images are already small enough. – frostymarvelous Sep 01 '14 at 11:15
  • As I said, try giving your program more memory with -Xmx argument. Also, why are you not caching images? – darijan Sep 01 '14 at 21:39
  • 1
    I finally decided to cache the created images rather than constantly recreate. Thanks. – frostymarvelous Sep 02 '14 at 08:58