简体   繁体   中英

Heap out of memory android

I've a simple java program which depends on an inputstream. I have to read in a 160 MB ecg file which works perfect on a normal jvm, but when i run this code in android it simply cant allocate that 160 MB and close my app.

Here is a code snipped:

//      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;
    }

I also tried to use DirectBuffer to go past the normal heap but still the out of memmory error like:

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

Is there any way to handle the data of an inputstream in a more efficient way? Or can I take some storage
eg a sdcard as "heap"?

best regards Lorezo

The VM heap won't be able to allocate an object of size 160 MB because many devices have 32 or 64 MB heap. Try reading the file in a loop (eg 4MB chunk) and skipping the number of bytes already read in the next iteration.

In general this is the wrong approach. These devices don't have that much memory available for applications, and if they do you need to remember that you need to share that memory with all the other apps that are running on the phone. However, here are a few things that I noticed right away.

First, you are trying to allocate the 160MB twice!

Once here:

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

and again here:

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

You might try rearranging this code so that you don't allocate the memory twice.

You will also need to set android:largeHeap="true" in the manifest.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM