致命的异常:java.lang.OutOfMemoryError:int[]长度为1083403672超出了虚拟机限制。

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

有没有想法为什么在从Intent中获取额外数据时会出现这种情况?

你在通知消息中发送了什么?内容长度很大吗?例如照片是否以Base64编码? - Yazan
1个回答

0

当你面对java.lang.OutOfMemoryError: Requested array size exceeds VM limit时,这意味着崩溃的应用程序试图分配一个大于Java虚拟机支持的数组。

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

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

将数组长度增加一到Integer.MAX_VALUE-1会导致熟悉的OutOfMemoryError Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit

解决方案是什么?

java.lang.OutOfMemoryError: Requested array size exceeds VM limit可能是以下情况之一的结果:

你的数组变得太大,最终大小在平台限制和Integer.MAX_INT之间。
你故意尝试分配比2^31-1元素更大的数组来测试极限。
在第一种情况下,请检查您的代码库,看看是否真的需要那么大的数组。也许你可以减小数组的大小并完成它。或者将数组分成较小的块,并将您需要处理的数据批量加载到适合您平台限制的批次中。
在第二种情况下,记住Java数组是由int索引的。因此,在使用平台内的标准数据结构时,您不能超过2^31-1个元素。实际上,在这种情况下,编译器已经阻止了您,宣布“错误:整数数字太大”在编译期间。
但是,如果您确实使用真正大型数据集进行工作,则需要重新考虑您的选项。您可以将需要处理的数据以较小的批次加载,并仍然使用标准Java工具,或者您可能会超越标准实用程序。实现这一点的一种方法是查看sun.misc.Unsafe类。这使您能够直接像在C中一样分配内存。

当接收到推送通知时,会触发此问题。我只是从意图包中获取字符串“message”。推送通知本身具有字符限制。因此无法理解实际原因可能是什么。 - Swati Singh
1
这个回答没有帮助。OP 明显没有分配任何东西。这是一个系统级别的解包问题。 - black

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接