Android 踏雷日記(1)String Out Of Memory by weitsai | CodeData
top

Android 踏雷日記(1)String Out Of Memory

分享:

今天在開發字典查詢 App 的時候發生了檔案讀出來存成 buffer 後, 再轉成 String 的過程中發生 Out Of Memory, 一直在百思不解的情況下上社群問了解法, 得到的結果是在 AndroidManifast.xml<applicaton> 標籤加入 android:largeHeap="true" 屬性解決, 可是有些手機卻不用就能夠正常執行, 到底是發生了什麼原因呢?讓我們來還原現場吧!

還原現場步驟:

  1. 環境介紹
  2. 把檔案放到 Assess 裡面
    把檔案放到 Assess 裡面
  3. 在 Activity 把這個檔案讀出來並轉成 String
    AssetManager assetManager = getAssets();
    InputStream ims = assetManager.open("dict.json");
    int size = ims.available();
    byte[] buffer = new byte[size];
    ims.read(buffer);
    ims.close();
    // 41175344
    System.out.println(buffer.length);
    // java.lang.OutOfMemoryError
    String s = new String(buffer);
    
    
  4. 執行後就會發生 Out Of Memory
    7975 AndroidRuntime E FATAL EXCEPTION: main
    7975 AndroidRuntime E java.lang.OutOfMemoryError
    7975 AndroidRuntime E at java.lang.String.<init>(String.java:255)
    7975 AndroidRuntime E at java.lang.String.<init>(String.java:171)
    7975 AndroidRuntime E at java.lang.String.<init>(String.java:141)
    7975 AndroidRuntime E at org.im.sundictionary.MainActivity.onCreate(MainActivity.java:66)
    7975 AndroidRuntime E at android.app.Activity.performCreate(Activity.java:5133)
    7975 AndroidRuntime E at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    7975 AndroidRuntime E at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
    7975 AndroidRuntime E at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
    7975 AndroidRuntime E at android.app.ActivityThread.access$600(ActivityThread.java:141)
    7975 AndroidRuntime E at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
    7975 AndroidRuntime E at android.os.Handler.dispatchMessage(Handler.java:99)
    7975 AndroidRuntime E at android.os.Looper.loop(Looper.java:137)
    7975 AndroidRuntime E at android.app.ActivityThread.main(ActivityThread.java:5103)
    7975 AndroidRuntime E at java.lang.reflect.Method.invokeNative(Native Method)
    7975 AndroidRuntime E at java.lang.reflect.Method.invoke(Method.java:525)
    7975 AndroidRuntime E at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    7975 AndroidRuntime E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    7975 AndroidRuntime E at dalvik.system.NativeStart.main(Native Method)
    
    

分析現場

現場還原了, 但是還是不知道兇手是怎麼樣殺死我的 App 的阿!! 原來是每個手機中各自的 App 可以使用的記憶體上限不同, 也就是有些手機可能是 96M, 而有一些則是 20M.

我們可以透過下面這段程式來瞭解自己手機每個 App 記憶體使用量上限是多少:

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int mMemoryClass = am.getMemoryClass();
long mLargeMemoryClass = am.getLargeMemoryClass();

android:largeHeap="true" 就是告訴系統這個 App 使用量可能會比較大, 請放寬限制!!

什麼!2.3.3 不支援 android:largeHeap="true" ?

雖然現在都是 Android 4.x 居多的時代, 但抱持著研究的精神當然還是得解決 2.3.3 的問題, 現在讓我們來一步一步解決問題吧.

  1. 建立 2.3 專用的 values 資料夾
    5481dc386da05
    建立 2.3 專用的 values 資料夾
  2. values-v14 下建立 bool.xml
    5481dc387e2d7
    在 values-v14 下建立 bool.xml
  3. bool.xml 加入 <bool name="largeheap">true</bool>
    bool.xml 檔案內容如下:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <bool name="largeheap">true</bool>
    </resources>
  4. AndroidManifst.xml 加入 android:largeHeap="@bool/largeheap"
  5. 大功告成啦!!

參考文獻

補充

那 largeHeap 的上限到底怎麼設定進去的呢? 那就得看一下 system 的設定檔, 如果你的裝置是 root 就可以使用下面的指令:

adb pull /system/build.prop [指定路徑]

接著打開 build.prop 然後跳到 85 行, 就可以看見你這個裝置的 hepap 的相關設定啦!

54812a0b33b67

如果有興趣也可以看看 system 在 build 的時候的設定檔唷~
https://github.com/android/platformframeworksbase/blob/master/core/jni/AndroidRuntime.cpp#L655

有趣的小發現

在研究的過程竟然發現有人做了一個可以編輯 build.prop 的 App, 作者我就沒有玩過了, 請勇者們去嘗試吧!!

https://play.google.com/store/apps/details?id=org.nathan.jf.build.prop.editor&hl=zh_HK

後續 >> Android 踏雷日記(2)更優雅地解決 String Out Of Memory

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

關於作者

我出生於一個無聲家庭,大二時便將我所學 Android App 發揮在自己家庭身上,聾啞人士長久以來沒有辦法像我們常人一樣可以打 110、119 報案,因此 iHelp 就此誕生。因為自己非常喜歡 Android,於是便在高雄成立 Android 高雄開發者社群 ,歡迎對 Android 有興趣的朋友來參與。

熱門論壇文章

熱門技術文章