3
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) 

它所指向的代码: -致命异常:java.lang.OutOfMemoryError:INT []长度1083403672的超过极限VM

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

...

任何想法为什么它会从意图中获取额外的内容吗?

+0

您在通知消息中发送了什么?内容长度巨大吗?ex base64编码的照片? – Yazan

回答

1

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

错误是由JVM中的本地代码抛出的。它发生在为JVM执行平台特定检查时为数组分配内存之前:在此平台中分配的数据结构是否可寻址。这个错误比你最初想象的要少。

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

通过一个增加阵列的长度为Integer.MAX_VALUE-1的结果,在熟悉的OutOfMemoryError异常在线程“主” java.lang.OutOfMemoryError:请求阵列大小超过限制VM

如何解决?

的java.lang.OutOfMemoryError:要求数组大小超过VM限制可以出现的以下任一情况的结果:

Your arrays grow too big and end up having a size between the platform limit and the Integer.MAX_INT

You deliberately try to allocate arrays larger than 2^31-1 elements to experiment with the limits.

在第一种情况下,检查你的代码库,看看是否你真的需要很大的数组。也许你可以减小数组的大小并完成它。或者将数组分成更小的数量,并将批量处理所需的数据加载到平台限制中。

在第二种情况下 - 记住Java数组是通过int索引的。因此,在平台内使用标准数据结构时,您不能超越数组中的2^31-1元素。事实上,在这种情况下,编译期间编译器宣布“错误:整数太大”已经阻塞了它。

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

+0

收到推送通知时会触发此问题。我只是从intent bundle中获取字符串“message”。推送通知本身具有字符限制。所以不能理解实际原因。 –