Verified Fix

How to Fix Android Error java.lang.OutOfMemoryError

If you are encountering error java.lang.OutOfMemoryError on Android, this guide will help you resolve it.

Quick Summary

The `java.lang.OutOfMemoryError` in Android indicates that the Java Virtual Machine (JVM) has run out of memory and cannot allocate more space for objects. This typically happens when your app is trying to use more memory than the system can provide, or when memory is not being managed efficiently.

Common Causes

  • Large Bitmap Handling: Loading and manipulating large bitmaps without proper scaling or recycling can consume excessive memory, leading to the error. Storing multiple high-resolution images in memory simultaneously will rapidly exhaust available memory, especially on devices with limited RAM.
  • Memory Leaks: Memory leaks occur when objects are no longer needed by the application but are still being held in memory. Over time, these accumulated leaks can exhaust the available memory.
  • Large Data Structures: Creating large arrays, Lists, or other data structures to store huge amounts of data without proper memory management can overwhelm the JVM. This is particularly relevant when fetching and caching data from network requests or databases.
  • Inefficient Code: Code that repeatedly allocates and deallocates memory in rapidly without reuse of objects, such as inside of loops, can lead to significant memory pressure and potentially trigger an `OutOfMemoryError`.
  • External Libraries: Certain poorly optimized third-party libraries can consume excessive amounts of memory without providing adequate cleanup methods. Ensure dependencies are reliable and updated frequently.

Step-by-Step Fixes

Method 1: Optimize Bitmap Handling

Step 1: Scale down images before loading them into memory. Use `BitmapFactory.Options` to specify a sample size when decoding images.

Step 2: Recycle bitmaps when they are no longer needed. Call `bitmap.recycle()` to release the memory used by the bitmap.

Step 3: Consider using libraries like Glide or Picasso for efficient image loading and caching. These libraries handle memory management automatically.

Step 4: Use WebP format for images, which provides better compression than JPEG or PNG.

Method 2: Address Memory Leaks

Step 1: Use tools like Android Profiler in Android Studio to identify memory leaks. Look for objects being retained when they should be garbage collected.

Step 2: Unregister listeners and callbacks when they are no longer needed, such as in `onPause()` or `onDestroy()` methods of Activities and Fragments.

Step 3: Avoid holding references to `Activity` contexts from background threads or static variables. Use `WeakReference` when you need to refer to `Activity` contexts to avoid leaking the `Activity`.

Step 4: Ensure that closing cursors and streams after use by using `try-finally` blocks for resource management.

Method 3: Optimize Data Structures

Step 1: Avoid storing large amounts of data in memory. If you need to process large datasets, use paging or streaming techniques.

Step 2: Reuse objects whenever possible to reduce memory allocation. Utilize object pools.

Step 3: Use appropriate data structures. For example, use `SparseArray` or `LongSparseArray` instead of `HashMap` when keys are integers or longs, respectively, to avoid auto-boxing overhead. Consider alternatives when there are many `null` values being stored.

Method 4: Increase Heap Size (If Necessary)

Step 1: This is a last resort and should be used with caution as it does not fix the underlying issue and could lead to other unexpected outcomes.

Step 2: Edit your application's `AndroidManifest.xml` file and add `android:largeHeap="true"` to the `<application>` tag.

Step 3: Test thoroughly to ensure no adverse effects from the larger heap size, and also, to see if you can still observe your application hitting the same memory limit/issue at a higher threshold.

Important: Enabling this may negatively affect performance and battery life. Proper memory management is always preferable.

Method 5: Use ProGuard/R8

Step 1: Ensure ProGuard or R8 is enabled in your `build.gradle` file. These tools optimize and shrink your code, potentially reducing memory footprint.

Step 2: Review the generated mapping files to understand how your code has been optimized and ensure that essential parts of your application were not stripped out inadvertently.

Step 3: Adjust your ProGuard/R8 rules as needed prevent excessive code shrinking that causes unexpected behavior.

Download Repair Tool →