Fatal Exception: java.lang.OutOfMemoryError: int[] of length 1083403672 exceeds the VM limit
at android.util.ArrayMap.allocArrays(ArrayMap.java:196)
at android.util.ArrayMap.ensureCapacity(ArrayMap.java:307)
at android.os.Bundle.unparcel(Bundle.java:247)
at android.os.Bundle.getString(Bundle.java:1118)
at com.test.example.pushnotification.LocalyticsReceiver.handleNotificationReceived(LocalyticsReceiver.java:61)
at com.test.example.pushnotification.LocalyticsReceiver.onReceive(LocalyticsReceiver.java:52)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2426)
at android.app.ActivityThread.access$1700(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
The code which it points to:-
String message = intent.getExtras().getString("message");
Please find the code snapshot below:
@Override
public void onReceive(Context context, Intent intent) {
String appKey = context.getResources().getString(R.string.localytics_api_key);
if (!TextUtils.isEmpty(appKey)) {
Localytics.integrate(context.getApplicationContext(), appKey);
}
if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) {
LocalyticsUtil.handleRegistration(intent);
} else {
Localytics.handlePushNotificationReceived(intent);
handleNotificationReceived(context, intent);
}
}
//handle notification when received
private void handleNotificationReceived(Context context, Intent intent) {
// Get the notification message
String message = intent.getExtras().getString("message");
...
Any idea why it occurs while fetching extra from an intent?
When you face the java.lang.OutOfMemoryError: Requested array size exceeds VM limit, this means that the application that crashes with the error is trying to allocate an array larger than the Java Virtual Machine can support.
The error is thrown by the native code within the JVM. It happens before allocating memory for an array when the JVM performs a platform-specific check: whether the allocated data structure is addressable in this platform. This error is less common than you might initially think.
The reason you only seldom face this error is that Java arrays are indexed by int. The maximum positive int in Java is 2^31 – 1 = 2,147,483,647. And the platform-specific limits can be really close to this number – for example on my 64bit MB Pro on Java 1.7 I can happily initialize arrays with up to 2,147,483,645 or Integer.MAX_VALUE-2 elements.
Increasing the length of the array by one to Integer.MAX_VALUE-1 results in the familiar OutOfMemoryError Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
What is the solution?
The java.lang.OutOfMemoryError: Requested array size exceeds VM limit can appear as a result of either of the following situations:
In the first case, check your code base to see whether you really need arrays that large. Maybe you could reduce the size of the arrays and be done with it. Or divide the array into smaller bulks and load the data you need to work with in batches fitting into your platform limit.
In the second case – remember that Java arrays are indexed by int. So you cannot go beyond 2^31-1 elements in your arrays when using the standard data structures within the platform. In fact, in this case you are already blocked by the compiler announcing “error: integer number too large” during compilation.
But if you really work with truly large data sets, you need to rethink your options. You can load the data you need to work with in smaller batches and still use standard Java tools, or you might go beyond the standard utilities. One way to achieve this is to look into the sun.misc.Unsafe class. This allows you to allocate memory directly like you would in C.