×

Discussion Board

Results 1 to 6 of 6
  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    43

    7650 and 3650 Canvas and FullCanvas memory

    I have just spent a week figuring out why my app, which works fine on smaller non-Nokia phones, kept running out of memory on the 3650. This was extremely frustrating because the 3650 is supposed to have gobs of memory. Anyway, I could rant for hours on all the things I had to try, but I now suspect the problem is the Nokia implementation of Canvas and FullCanvas. Let me explain.

    In my app (a game) I have a class (called UICanvas) that extends FullCanvas (at least this was how is originally worked). Anyway, during the execution of my game, I would need to create numerous instances of UICanvas to display as part of the game. However, I kept running out of memory when doing this. I tried different tests extending either Canvas or FullCanvas, and the problem existed in both cases. I began to suspect a day ago that the problem was that maybe Nokia Canvas and FullCanvas secretly allocated their own big chunks of memory to store the last screen painted on them, should a user wish to return to the screen.

    To test my theory, I rewrote my code so that now my UICanvas class does NOT extend either Canvas or FullCanvas. Instead I created a new class called FullCanvasImp that extends FullCanvas. FullCanvasImpl is a "bare bones" class that simply contains a reference to a UICanvas, and contains a paint() method that simply calles the paint method on the UICanvas object that is stored in the FullCanvasImpl object. (See code below). I changed UICanvas so that instead of extending FullCanvas, it just it just contains a static reference to a single instance of FullCanvasImpl, where this FullCanvasImpl instance is shared among all my UICanvas objects.
    In other words, now my UICanvas object just contain the data needed to draw on a FullCanvas, but the actual FullCanvas object on which I draw the data is just this static instance of FullCanvasImpl.

    The code to switch Displayables is bit more complicated now because the VM doesn't really think you are switching Displayables - it just thinks you are painting different things to the same Displayable (same FullCanvasImpl). This means that the VM does not automatically call showNotify or hideNotify, instead I had to do that manually inside a method I wrote called setCurrentDisplay() which is a wrapper for Display.getDisplay(this).setCurrent(newdisplay). My setCurrentDisplay method calls the showNotify and hideNotify methods manually when "switching" between different instances of UICanvas.

    Believe it or not, this all worked like a charm. I no longer run out of memory.

    So, I have a comment/warning for developers, and I have a question for Nokia.

    NOKIA PLEASE ANSWER THIS!

    My comment: Always use a very small number of instances of any object that extends FullCanvas. We were all taught to create a class that extends Canvas or FullCanvas, and just create multiple instances of this class for multiple interface Displayables. While this works fine on non-Nokia phones, it WILL NOT WORK on the 3650/7650 (maybe not even on other Nokia phones). Instead, you will need to create one or at most two instances of any object that extends FullCanvas, and you will need to write your interface code such that different interfaces draw to these same one or two FullCanvas objects. It is really best to use just one FullCanvas, that way you can use double buffering to avoid the screen switch flicker that occurs.

    Now for my question, which I already partially posed. Nokia: Does your Canvas and FullCanvas implementation allocate a big chunk of memory for the display? Is this why my app kept running out of memory when I allocate multiple objects that extend FullCanvas? I kept checking the free memory and total memory, and I kept running out even when these said that the total memory was only 464KB. This is at least 1MB less than I thought the phone had, so of course I was surprised. But If Canvas and FullCanvas need to allocate their own big display buffers, and if this memory does not show up in the runtime.totalMemory() command, then I would expect to see exactly the behavior I did see. Anyway, why would Nokia use this approach? As I said, this same app works fine on phones with much less memory!

    So Nokia what's the story here? PLEASE ANSWER!

    Good luck to all


    -------------------------------------------------------------------------------
    Here's my FullCanvasImpl class:

    public class FullCanvasImpl extends FullCanvas {
    UICanvas currUI;

    public FullCanvasImpl()
    {
    currUI=null;
    }

    public void paint(Graphics g) {
    System.out.println("In FullCanvasImpl.paint for id = "+currUI.id);
    if (currUI!=null) currUI.paint(g);
    }

    protected void keyPressed(int keyCode)
    {
    if (currUI!=null) currUI.keyPressed(keyCode);
    }
    }

  2. #2
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280
    This is very interesting.
    I've had unexplicable bugs on the 7650 since I started using it. The same app runs great on a 3510i.
    I have 4 instances of FullCanvas subclasses open most of the time, and the game will get stuck without any exception or warning or anything, it just stops dead on it's tracks.
    I will try out your solution and let you know if it helped...

    shmoove

  3. #3
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280
    I'm sorry to sat it didn't help me. My app still hangs.
    I am going to keep this design though, since it saves runtime resources; and also it makes it easier to put debug information on screen, because I can round up all the info on the FullCanvasImpl class.

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    12
    Hi,

    This may be a solution to another problem posted onto the forums.

    I have tried to implement your solution but am having trouble - would it be possible for you to provide a more extended source example.


    Regards,
    Lee

  5. #5
    Registered User
    Join Date
    Jul 2003
    Location
    Finland, Tampere
    Posts
    1,113
    Well, guys, I would also prefer it working a bit other way, but we were warned, wern't we?

    In almost every J2ME guideline they advice to use single reference to the same object whenever possible. It's up to implementation how to manage its Canvas or FullScreen. Unfortunately Nokia chose not the most comfortable way.

    Also I personally believe that changing Displayables was meant mostly for Form style objects. Nokia guys just didn't think that anybody would like to use several FullCanvases at the same moment

  6. #6
    Regular Contributor
    Join Date
    Apr 2003
    Location
    Slovakia/Bratislava
    Posts
    67
    I simple don't understand the need for more instances of canvas...

    I hope reading this article will help you find better solution...

    http://wireless.java.sun.com/midp/ttips/flickgraphics/
    http://www.onjava.com/lpt/a/1371

    regards

    Tom

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×