1

我有一个依赖于输入流的简单 java 程序。我必须读取一个 160 MB 的 ecg 文件,该文件在普通 jvm 上运行完美,但是当我在 android 中运行此代码时,它根本无法分配 160 MB 并关闭我的应用程序。

这是一段代码:

//      reads the ecg file into a stream and stores it in the InputArray
    public byte[] readStream() throws IOException{
        FileInputStream inputFile = new FileInputStream(getDataPath());
        setBytesToSkip(0);
        inputFile.skip(getBytesToSkip());
        setLengthOfInputFile(inputFile.available());
        byte[] InputArray = new byte[getLengthOfInputFile()];
        setInputArray(InputArray);
        inputFile.read(getInputArray());
        inputFile.close();
        return inputArray;

    }
//              writes the bytes of the inputArray into a buffer bb
            public ByteBuffer bufferStream(byte[] array){
        inputArray = array;
        setBufferOffset(0);
        setBufferByteReadLength(getLengthOfInputFile());

        ByteBuffer bb = ByteBuffer.allocateDirect(getBufferByteReadLength());
        bb.order(ByteOrder.LITTLE_ENDIAN);
        bb.put(getInputArray(), getBufferOffset(), getBufferByteReadLength());
        return bb;
    }

我还尝试使用 DirectBuffer 越过正常堆,但仍然出现内存不足错误,例如:

dalvikvm-heap  PID:1715  Out of memory on a 167230992-byte allocation

有没有办法以更有效的方式处理输入流的数据?或者我可以拿一些存储空间,
例如一个 sdcard 作为“堆”吗?

最好的问候洛雷佐

4

2 回答 2

1

一般来说,这是错误的方法。这些设备没有那么多内存可供应用程序使用,如果有,您需要记住,您需要与手机上运行的所有其他应用程序共享该内存。但是,这里有一些我马上注意到的事情。

首先,您尝试分配 160MB 两次!

一旦来到这里:

byte[] InputArray = new byte[getLengthOfInputFile()];

再次在这里:

ByteBuffer bb = ByteBuffer.allocateDirect(getBufferByteReadLength());

您可以尝试重新排列此代码,以免分配内存两次。

您还需要android:largeHeap="true"在清单中进行设置。

于 2013-11-09T13:04:58.613 回答
1

VM 堆将无法分配大小为 160 MB 的对象,因为许多设备都有 32 或 64 MB 的堆。尝试循环读取文件(例如 4MB 块)并跳过下一次迭代中已读取的字节数。

于 2013-11-09T12:37:47.563 回答