JavaME Images - LWUIT Eats All Memory

I am writing a MIDlet using LWUIT, and the images seem to absorb an incredible amount of memory. All the images I use are PNGs and are packaged in a JAR file. I load them using the standard Image.createImage (URL) method. An application has several forms, and each has several button shortcuts, however, I am sure that only the active form is stored in memory (I know that it is not very reliable, but Runtime.freeMemory () seems to confirm this).

The application has proven itself in the resolution of 240x320, but moving it to 480x640 and using the corresponding larger images for the user interface causes errors in memory. That the application, among other things, uploads deleted images. The application works fine until it reaches this point. After loading several PNGs and returning to the main menu, an error occurs from the memory. Naturally, I looked at the amount of memory that the main menu uses, and it was pretty shocking. These are just two tags with images and four buttons. Each button has three images used for style.setIcon, setPressedIcon and setRolloverIcon. Images range from 15 to 25 KB, but when deleting two of the three images used for each button (a total of 8 images), Runtime.freeMemory () showed a stunning 1 MB memory reduction.

As I see this, I either have a lot of memory leaks (which I don’t think I do, but the memory leaks are not exactly known, which are easily tracked), I am doing something terribly wrong with image processing or there really is not a problem and I just need to zoom out.

If anyone has the opportunity to offer, I would really appreciate it.

+6
java-me midlet lwuit
source share
5 answers

Mobile devices are usually very small in memory. Therefore, you need to use some tricks to save and use memory.

We had the same problem in our project, and we solved it like that.

for uploaded images: Create a cache in which you place your images. If you need an image, check if it is in the cachemap, if it does not load it and puts it there, if it is, use it. if the memory is full, delete the oldest image in cachemap and try again.

for other resource images: keep them in memory only until you see them, if you do not see them, break the link and gc will do the cleaning for you.

Hope this helps.

+2
source share

There are several things that can happen here:

  • You may have seen memory used before garbage collection that does not match the actual memory used by your application.
  • Some third-party code that you use may combine some internal data structures to minimize distribution. While pooling is a viable strategy, sometimes it looks like a leak. In this case, see if there is an API to "close" or "delete" objects that you do not need.
  • Finally, you may have a leak. In this case, you need to get more detailed information about what is happening in the VM emulator (although keep in mind that this does not necessarily coincide with the virtual machine).

Make sure your emulator uses JRE 1.6 to support JVM. If you need to use the runtime libraries from erlyer JDK, use -Xbootclasspath:<path-to-rt.jar> .

Then, after your application enters the state you want to see, execute %JAVA_HOME%\bin\jmap -dump:format=b,file=heap.bin <pid> (if you do not know the identifier of your process, use jps )

You now have a JVM heap dump. You can jhat it using jhat (comes with the JDK, a little harder to use) or with some third-party profilers (my YourKit preferences are commercial, but they have a limited time eval license)

+1
source share

I had a similar problem with LWUIT on Java DTV. Have you tried to clear images when you no longer need them (getAWTImage (). Flush ())?

+1
source share

Use EncodedImage and resource files whenever possible (resource files use EncodedImage by default). Read javadoc for such. Other comments are also true that you need to really observe the amount of memory, even high RAM Android / iOS devices end up pretty quickly with multiple images.

Avoid scaling that effectively eliminates EncodedImage .

+1
source share

Do you think that possibly loading the same image from the JAR many times leads to the creation of many separate image objects (with identical contents) instead of reusing one instance for each individual image? This is my first guess.

0
source share

All Articles