簡體   English   中英

Android 應用程序在 EDF 文件解析時運行到 java.lang.OutOfMemoryError

[英]Android App running into java.lang.OutOfMemoryError while EDF file parsing

我搜索了類似的主題,但找不到任何與 EDF 文件和 Out of memory 錯誤相關的內容。

所以,這是我的問題:我正在 Android 工作室開發一個 Android 應用程序,它瀏覽文件,選擇一個“.edf”文件並解析它。 但是對於某些文件,它會引發以下錯誤(帶有堆棧跟蹤):

I/xample.styleap: Starting a blocking GC Alloc
    Starting a blocking GC Alloc
I/xample.styleap: Alloc concurrent copying GC freed 15804(1107KB) AllocSpace objects, 5(108KB) LOS objects, 86% free, 1955KB/13MB, paused 148us total 44.577ms
    Starting a blocking GC Alloc
I/xample.styleap: Alloc young concurrent copying GC freed 0(15KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 1955KB/13MB, paused 120us total 16.603ms
    Starting a blocking GC Alloc
I/xample.styleap: Alloc concurrent copying GC freed 2019(110KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 1844KB/13MB, paused 83us total 25.049ms
    Forcing collection of SoftReferences for 488MB allocation
    Starting a blocking GC Alloc
I/xample.styleap: Alloc concurrent copying GC freed 2053(69KB) AllocSpace objects, 0(0B) LOS objects, 87% free, 1790KB/13MB, paused 75us total 22.140ms
W/xample.styleap: Throwing OutOfMemoryError "Failed to allocate a 512000012 byte allocation with 12582912 free bytes and 190MB until OOM, target footprint 14416192, growth limit 201326592" (VmSize 1212600 kB)
I/xample.styleap: Starting a blocking GC Alloc
    Starting a blocking GC Alloc
I/xample.styleap: Alloc young concurrent copying GC freed 4(31KB) AllocSpace objects, 0(0B) LOS objects, 87% free, 1774KB/13MB, paused 79us total 15.057ms
I/xample.styleap: Starting a blocking GC Alloc
I/xample.styleap: Alloc concurrent copying GC freed 3(16KB) AllocSpace objects, 0(0B) LOS objects, 87% free, 1774KB/13MB, paused 83us total 23.495ms
    Forcing collection of SoftReferences for 488MB allocation
    Starting a blocking GC Alloc
I/xample.styleap: Alloc concurrent copying GC freed 50(17KB) AllocSpace objects, 0(0B) LOS objects, 87% free, 1788KB/13MB, paused 73us total 22.532ms
W/xample.styleap: Throwing OutOfMemoryError "Failed to allocate a 512000016 byte allocation with 12582912 free bytes and 190MB until OOM, target footprint 14414784, growth limit 201326592" (VmSize 1212600 kB)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.styleapp, PID: 30041
    java.lang.OutOfMemoryError: Failed to allocate a 512000016 byte allocation with 12582912 free bytes and 190MB until OOM, target footprint 14414784, growth limit 201326592
        at br.unb.biologiaanimal.edf.EDFReader.readRecords(EDFReader.java:106)
        at br.unb.biologiaanimal.edf.EDFReader.<init>(EDFReader.java:25)
        at br.unb.biologiaanimal.edf.EDF.<init>(EDF.java:24)
        at com.example.styleapp.MainActivity.runEDFfile(MainActivity.java:100)
        at com.example.styleapp.MainActivity.access$000(MainActivity.java:24)
        at com.example.styleapp.MainActivity$2.onMenuItemClick(MainActivity.java:82)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:154)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:981)
        at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:625)
        at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
        at android.view.View.performClick(View.java:7140)
        at android.view.View.performClickInternal(View.java:7117)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27355)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7410)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
W/System: A resource failed to call close.

我正在為 java 使用 EDF 解析器庫: https://github.com/lab-neuro-comp/EDF

我的源代碼(MainActivity.java):

import br.unb.biologiaanimal.edf.EDF;
EDF edf = new EDF(filepath);

當使用特定文件路徑調用 EDF 構造函數時,它會失敗。 很多地方都說它失敗的原因是 JVM/Android 中的 VM 不足或堆大小。 但我想我也已經處理好了:

里面 studio.vmoptions

-Xmx2048m

我猜這指定了 Android Studio 的 JVM VM 大小。 我還打印了 Java 虛擬機將嘗試使用的 memory 的最大數量:

Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();

這打印

201326592

這意味着大約有 201MB 可用。

那么,當它成功加載 4.2MB EDF 文件時,它在加載 1.9 MB EDF 文件時失敗(內存不足)的原因是什么?

由於 EDF 解析庫的邏輯錯誤,它失敗了。 The EDF class method looks for a header called "duration" (the reason is unclear) and uses it for subsequent arithmetic operations where it use the header value to allocate array memory etc. at times the duration value is float and that leads to wrong arithmetic結果值也變得非常大。 在那里它無法分配 memory。 這是代碼片段:

private void readRecords(FileInputStream stream)
    throws IOException
    {
        records = new HashMap();
        int[] numberSamples = getNumberSamples();
        int[] sampling = new int[numberSignals];
        int duration = paramToInt("duration");
        int dataRecords = paramToInt("datarecords");
        byte[][] recordList = new byte[numberSignals][5];
        String[] labels = getLabels();
        byte[] buffer = null;

        // Initalizing variables
        for (int i = 0; i < numberSignals; ++i)
        {
            sampling[i] = duration * numberSamples[i];
            recordList[i] = null;
        }

        // Reading records
        for (int d = 0; d < dataRecords; ++d)
        {
            for (int i = 0; i < numberSignals; ++i)
            {
                duration = 2 * sampling[i];
                buffer = new byte[duration];
                stream.read(buffer);
                // TODO Make this insertion faster. Maybe a queue?
                recordList[i] = (recordList[i] == null)?
                    buffer :
                    EDFUtil.insert(recordList[i], buffer);
            }
        }

        // Packing records
        for (int i = 0; i < numberSignals; ++i)
        {
            String label = labels[i].trim();
            records.put(label, recordList[i]);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM