致命异常:java.lang.OutOfMemoryError:长度为1083403672的int []超出VM限制

时间:2016-08-10 13:16:08

标签: android android-intent android-broadcastreceiver localytics

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)

它指向的代码: -

String message = intent.getExtras().getString("message");

请在下面找到代码快照:

 @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");

...

知道为什么在从意图中获取额外内容时会发生这种情况吗?

1 个答案:

答案 0 :(得分:0)

当您面对java.lang.OutOfMemoryError时:请求的数组大小超过VM限制,这意味着崩溃的应用程序正在尝试分配大于Java虚拟机可以支持的数组。

JVM中的本机代码引发错误。当JVM执行特定于平台的检查时,它会在为阵列分配内存之前发生:分配的数据结构在此平台中是否可寻址。这个错误不像你最初想的那么常见。

您很少遇到此错误的原因是Java数组由int索引。 Java中的最大正int是2 ^ 31 - 1 = 2,147,483,647。特定于平台的限制可以非常接近这个数字 - 例如在Java 1.7上的64位MB Pro上,我可以愉快地初始化最多2,147,483,645或Integer.MAX_VALUE-2元素的数组。

将数组的长度增加1到Integer.MAX_VALUE-1会导致线程" main"中出现熟悉的OutOfMemoryError异常。 java.lang.OutOfMemoryError:请求的数组大小超过VM限制

解决方案是什么?

java.lang.OutOfMemoryError:请求的数组大小超过VM限制可能会因以下任一情况而出现:

  

您的阵列变得太大,最终的大小在平台限制和Integer.MAX_INT之间

     

您故意尝试将大于2 ^ 31-1个元素的数组分配给   试验极限。

在第一种情况下,检查代码库以确定是否确实需要大型数组。也许你可以减少数组的大小并完成它。或者将数组划分为更小的数量,然后按照适合平台限制的批量加载需要处理的数据。

在第二种情况下 - 记住Java数组是由int索引的。因此,在平台中使用标准数据结构时,您不能超越阵列中的2 ^ 31-1个元素。实际上,在这种情况下,编译器在编译过程中已经阻止了“错误:整数过大”的编译器。

但如果您真的使用真正的大型数据集,则需要重新考虑您的选择。您可以以较小的批量加载需要使用的数据,并且仍然使用标准Java工具,或者您可能超出标准实用程序。实现此目的的一种方法是查看sun.misc.Unsafe类。这允许您直接分配内存,就像在C中一样。