堆内存安卓机器人

时间:2013-11-09 12:30:47

标签: android heap-memory

我有一个简单的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超过正常堆但仍然出现memmory错误,如:

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

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

最好的问候Lorezo

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

首先,你试图分配160MB两次!

来到这里:

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

再来一次:

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

您可以尝试重新排列此代码,这样就不会分配内存两次。

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