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」。推送通知本身具有字符限制。所以不能理解實際原因。 –