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) 

Код, который он указывает: -Fatal Exception: 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 Virtual Machine.

Ошибка вызвана нативным кодом в JVM. Это происходит, прежде чем выделять память для массива, когда JVM выполняет проверку конкретной платформы: разрешена ли распределенная структура данных на этой платформе. Эта ошибка встречается менее часто, чем вы могли бы подумать.

Причина, по которой вы редко сталкиваетесь с этой ошибкой, заключается в том, что массивы Java индексируются int. Максимальный положительный 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 в потоке «основной» 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.is.Unsafe. Это позволяет вам распределять память так же, как в C.

+0

Эта проблема запускается при получении push-уведомления. И я просто собираю строку «сообщение» из комплекта намерений. Самонаводное уведомление имеет ограничение по характеру. Так что не в состоянии понять, что может быть причиной. –