Jump to content

how to avoid "out of memory" exception on phones with low heap?

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
2 replies to this topic

#1
amrosama

amrosama

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 8,674 posts
Hi guys,
Im working on a midlet that fetches data from internet. it works fine on most cases but when heap size is less than 1 mb (or free memory), i get the lousy out of memory exception.
i tracked down the part of my code that makes this exception.

                this.connection = (HttpConnection) Connector.open(url,Connector.READ);

                this.readerStream=this.connection.openInputStream();

                this.inputStreamData=new byte[(int)this.connection.getLength()];

                this.dataInputStream=new DataInputStream(this.readerStream);

                this.dataInputStream.readFully(this.inputStreamData);   //bad code 

                //return new String(this.inputStreamData);

                this.songContentContainer.add(new String(this.inputStreamData));//setting the result to the display

i tried using "sustem.gc()" at the beginning of the function and tried splitting the data into small strings and add them to the container on the fly using this code:

                    this.connection = (HttpConnection) Connector.open(url,Connector.READ);

                    this.readerStream=this.connection.openInputStream();

                    this.inputStreamData=new byte[50];

                    this.dataInputStream=new DataInputStream(this.readerStream);

                    int i=0;

                    int ch;

                    System.gc();

                    while ((ch= this.dataInputStream.read())!= -1) {

                             this.inputStreamData[i]=(byte)ch;

                             if(i==49){

                                 this.songContentContainer.add(new String(this.inputStreamData));

                                this.inputStreamData=new byte[50];

                                i=0;

                             }else

                                 i++;

                    }

                    this.songContentContainer.add(new String(this.inputStreamData));

the problem is basically that i have a really big text that i want to show, might be over 1500 character (its a song lyrics)

any suggestions on how i can fix or avoid this on phones with low memory?
yo homie i heard you like one-line codes so i put a one line code that evals a decrypted one line code that prints "i love one line codes"
eval(base64_decode("cHJpbnQgJ2kgbG92ZSBvbmUtbGluZSBjb2Rlcyc7"));
www.amrosama.com | the unholy methods of javascript

#2
dbug

dbug

    Programmer

  • Members
  • PipPipPipPip
  • 155 posts
In the second option you should reuse the inputStreamData array instead of reallocating it. Anyway this should not exhaust all the memory. Do you repeat this action many times or use more memory doing other things ? is it possible that some connections give you a lot more of 1500 characters ?

You could use the Runtime object to track the memory usage and determine where free memory drops drastically, or if it is a gradual loss.

Runtime rt = Runtime.getRuntime();

rt.freeMemory(); // current free memory

rt.totalMemory(); // total memory available
One thing you can do to free memory as soon as possible is to delete references to objects when they are not needed anymore. This allows the garbage collector to recover the used memory earlier. This can be important in long functions that create a lot of objects. If you don't remove the references, the objects cannot be freed until the function terminates and local variables are automatically destroyed.

For example, when you stablish the connection and read the received data, you can close it just after the reading and set this.connection = null to remove the reference to the object:

                this.connection = (HttpConnection) Connector.open(url,Connector.READ);

                this.readerStream=this.connection.openInputStream();

                this.inputStreamData=new byte[(int)this.connection.getLength()];

                this.dataInputStream=new DataInputStream(this.readerStream);

                this.dataInputStream.readFully(this.inputStreamData);

                [COLOR="red"]this.readerStream.close();

                this.connection.close();

                this.dataInputStream = null;

                this.readerStream = null;

                this.connection = null;[/COLOR]

                //return new String(this.inputStreamData);

                this.songContentContainer.add(new String(this.inputStreamData));//setting the result to the display

                [COLOR="red"]this.inputStreamData = null;[/COLOR]
Maybe this helps to alleviate a bit the memory problem.

#3
amrosama

amrosama

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 8,674 posts
Thank you very much dbug for your help and fast response.

Quote

Do you repeat this action many times or use more memory doing other things ? is it possible that some connections give you a lot more of 1500 characters ?
-actually its a user triggered action to search internet for a song lyrics, so it runs once. yes im using j2me polish framework, its uses lots of memory (512kb minimum)
-it varies according to the song. i found out this bug while trying to get a song called "cult" by slayer. really long song

thanks to your response, I printed out the free memory/ memory before and after this function and it only used about 10kb of memory and i have about 400kb of free memory (configured emulator heap memory to 1024kb)
So it wasnt the way i handle the connection, it was about how i represent the result. the memory was consumed because of the j2me polish styling of the presented text. what i did to fix this is to view the lyrics in completely separate displayable so the garbage collector cleans the other displayables(or any other unkown reason)

thank you again for your help, you deserve a nice juicy +rep :amr:
yo homie i heard you like one-line codes so i put a one line code that evals a decrypted one line code that prints "i love one line codes"
eval(base64_decode("cHJpbnQgJ2kgbG92ZSBvbmUtbGluZSBjb2Rlcyc7"));
www.amrosama.com | the unholy methods of javascript