05-19-2011 10:35 PM
Hello everyone,
I write a simple app, and move from my splash screen to menu screen. In MenuScreen class I have a paintBackground method to draw background image. Recently I noticed severe memory leak in this method:
VerticalFieldManager vf = new VerticalFieldManager(VerticalFieldManager.USE_ALL_WIDTH | VerticalFieldManager.USE_ALL_HEIGHT | VerticalFieldManager.NO_VERTICAL_SCROLL | VerticalFieldManager.NO_VERTICAL_SCROLLBAR) { public void paintBackground(Graphics graphics) { graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), bg_img, 0, 0); // System.out.println("========================="); super.paintBackground(graphics); } };
If I remove comments on println, it will echo infinitely. I checked, class is created once, so there shouldn't be loop of creating many instances of MenuClass.
Does anyone know what may cause such a behavior?
Solved! Go to Solution.
05-19-2011 10:36 PM
05-19-2011 11:35 PM
So far nobody has answered, and that's the answer I found by occasion.
Some notes:
SplashScreen which invoked MenuScreen was closed, only 1 screen was in stack.
Here is the soulution: just replace paintBackground with paint method:
public void paint(Graphics graphics) {
graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), bg_img, 0, 0);
System.out.println("=========================");
super.paintBackground(graphics);
}
}; That's it, now it will echo "===============" only once!
05-20-2011 11:38 AM
05-20-2011 01:47 PM
Thanx for replying, I just tried new way:
public void paintBackground(Graphics graphics) {
super.paintBackground(graphics);
graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), bg_img, 0, 0);
System.out.println("=========================");
}and it loops heavily. BTW, now I don't use this way of rendering background image at all, but use setBackground method. I profiled this chunk several times, results say no memory leak, but something tells me its still here.
05-20-2011 01:55 PM
Also one question: how comes when I print out:
System.out.println("=============>Number of Screens: "+UiApplication.getUiApplication().getScreenCount( ));it returns 0? I'm still able to see my screen rendered and running. I closed previous screen using popScreen() method.
05-21-2011 02:07 PM
As previously noted, paintBackground is called by the framework (FYI I believe it is usually done as part of the standard paint method) and should not be invoked by your code. If you are seeing it invoked repeatedly, then I can only assume that you are repeatedly invoking it in some way, possibly by some processing you are doing that is actually invoking the paint method (repeated invalidates, constantly updating the screen and the like). But put a break point in there, and see what the stack trace tells you, that should give you a good clue as to why this is being used repeatedly.
Also, having looked at your original code, I can't see how it, by itself, is causing a memory leak. Why do you think that it actually is?
With respect to this question:
why is UiApplication.getUiApplication().getScreenCount()) == 0?
Sorry I have no idea. Where are you actually invoking this?
BTW, not sure what happens here:
graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), bg_img, 0, 0);
if you Bitmap is not getWidth() * getHeight() at least.
05-21-2011 10:01 PM
Thank you for replying! I'm gonna try to implement your tips soon. Actually, I thought that it was *memory leak* seeing infinitely printed "===================" and my simulator was almost *shaking* 'cos of crazy frequency screen repainting. Now I use seBackground code for VerticalManager with buttons, but this shaking tells me something is going wrong, though I don't trace out "===============" now.
Regarding UiApplication.getUiApplication().getScre
05-22-2011 01:44 AM
Ok, now I'm 100% sure there is a loop. Somehow when I overwrite paint() method in VerticalFieldManager it gets called by MenuScreen, which is very strange for me. Take a look at code and screenshots I made, please:
import net.rim.blackberry.api.browser.Browser; import net.rim.blackberry.api.browser.BrowserSession; import net.rim.device.api.system.Bitmap; import net.rim.device.api.system.Characters; import net.rim.device.api.system.KeyListener; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.BitmapField; import net.rim.device.api.ui.container.MainScreen; import net.rim.device.api.ui.container.VerticalFieldManager; import net.rim.device.api.ui.decor.Background; import net.rim.device.api.ui.decor.BackgroundFactory; public class MainMenu extends MainScreen { //Buttons of Main menu Bitmap newbtn_img; Bitmap continuebtn_img; Bitmap tutorialbtn_img; Bitmap morebtn_img; Bitmap bg_img; //Images for the buttons of Main menu BitmapField newbtn; BitmapField continuebtn; BitmapField tutorialbtn; BitmapField morebtn; Background bg; public MainMenu() { super(NO_VERTICAL_SCROLL); //I call this to double-check previous screen was closed properly; it prints out 1 System.out.println("0000000000000000000000000000>N umber of Screens: "+UiApplication.getUiApplication().getScreenCount( )); bg_img = Bitmap.getBitmapResource("menu_screen.png"); //newbtn_img = Bitmap.getBitmapResource("new_game.png"); //continuebtn_img = Bitmap.getBitmapResource("tutorial.png"); //tutorialbtn_img = Bitmap.getBitmapResource("tutorial.png"); //morebtn_img = Bitmap.getBitmapResource("more_games.png"); //bg = BackgroundFactory.createBitmapBackground(bg_img); VerticalFieldManager vf = new VerticalFieldManager(VerticalFieldManager.USE_ALL_ WIDTH | VerticalFieldManager.USE_ALL_HEIGHT | VerticalFieldManager.NO_VERTICAL_SCROLL | VerticalFieldManager.NO_VERTICAL_SCROLLBAR) { public void paint(Graphics graphics) { graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), bg_img, 0, 0); System.out.println("========================="); //BREAKPOINT HERE super.paint(graphics); } }; //vf.setBackground(bg); // vf.add(newbtn); // vf.add(continuebtn); // vf.add(tutorialbtn); // vf.add(morebtn); add(vf); } }
There are a few buttons in original, they for sure safe and don't cause any problems. I decided to remove them for now for better overview of real problem.
Now, what I get in console:
And what I get from the debugger window:
When I press F8 it returns me this MainMenu.paint() infinitely.
05-22-2011 01:57 AM