Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Posts: 18
Registered: ‎11-12-2009
My Device: Bold 9000
Accepted Solution

SVG Memory Leak

[ Edited ]

First the required info:

Dev Environment:
- Eclipse 3.4.1 + JDE Plugin
- Component Packs:,,,,,
- I toggle between 4.6 and 5.0 mostly... 5.0 for touch, 4.6 for compatibility (and the 9000 is the only device I have access to)


Test Environment:
- Device 9000,
- Simulator 9000,
- Simulator 9550,
- and other sims for various OS levels, but the above 3 are my primary tools



My original discovery that I had a huge memory leak in my SVG code came when I discovered that each successive run of my app took much longer to get past my splash screen:



Start the app, time the splash screen, and once the main screen appears exit.  Repeat, and record the results as above.  4 minutes of splash screen is somewhat troubling... of course while the splash is showing we see the GC spinning icon in the center of the screen.  At first it looks like FULL GC, then it starts getting longer and longer which leads me to beleive we enter the Emergency GC.


First question:  when an app calls System.exit(0), shouldn't all of its memory be recovered?  Isn't this the purpose of the VM?  I've watched both the LMM and GC videos, and I think the one trouble spot is to deal with PersistantObjects, and yes I am using those, and I may have a leak in there, but it can't account for 10's of MB of RAM getting chewed up and not being recovered by the GC.

So I've narrowed it down to a single call in SVG land... I think the Plazmic Media Engine is behaving quite badly...  Or I don't understand this SVG methodology as well as I should.

Here's a sample App that will consume all memory on a device and terminate with an out of memory exception. 


Second question: What is wrong with this code?  (I beleive this will trigger an Emergency GC towards the end... before the OOM exception)



package SVGMemoryLeak;

import javax.microedition.m2g.SVGImage;
import javax.microedition.m2g.ScalableGraphics;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGSVGElement;

import net.rim.device.api.system.Backlight;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.container.MainScreen;

public class MemoryLeak extends UiApplication {

	public static void main(String[] args) {
		MemoryLeak leak = new MemoryLeak();


	public MemoryLeak(){
		pushScreen(new svgScreen());
	class svgScreen extends MainScreen implements Runnable{
	    protected static final String SVG_NAMESPACE_URI = "http://www.w3.org/2000/svg";
	    protected static final String XLINK_NAMESPACE_URI = "http://www.w3.org/1999/xlink";

		private SVGImage image;
		private Document doc;
		private SVGSVGElement svgTopElement;
		private SVGElement svgGroup;
		private ScalableGraphics scalablegraphics;
		private int h;
		private int w;
		private int counter=0;

		public svgScreen(){
			scalablegraphics = ScalableGraphics.createInstance();
	        image = SVGImage.createEmptyImage(null);
	        doc = image.getDocument();
	        w = Display.getWidth();
	        h = Display.getHeight();
	        image.setViewportHeight((int) h);
	        image.setViewportWidth((int) w);
	        // Get our root svg element.
	        svgTopElement = (SVGSVGElement)doc.getDocumentElement();        
	        svgTopElement.setFloatTrait("width", w);        
	        svgTopElement.setFloatTrait("height", h);        
	        svgGroup = (SVGElement)doc.createElementNS(SVG_NAMESPACE_URI, "g");
	        String color = "#4444ff";  //blue
	        svgGroup.setTrait("color", color);
	        svgGroup.setTrait("stroke", color);
	        svgGroup.setFloatTrait("stroke-width", 2);
	        svgGroup.setTrait("fill", color);
	        svgGroup.setFloatTrait("fill-opacity", 0.25f);

	        //start the animation...
	        UiApplication.getUiApplication().invokeLater(this, 50, true);			
		protected SVGElement NewCircle(float x, float y, float r) {
			SVGElement e;

	        e = (SVGElement)doc.createElementNS(SVG_NAMESPACE_URI, "circle");
	        e.setFloatTrait("cx", x);
	        e.setFloatTrait("cy", y);
	        e.setFloatTrait("r", r);
	        return e;

		protected SVGElement NewText(String t, float x, float y){
			SVGElement e;

			e = (SVGElement)doc.createElementNS(SVG_NAMESPACE_URI, "text");
	        e.setFloatTrait("x", x);
	    	e.setFloatTrait("y", y);
	        e.setTrait("#text", t);
	        return e;
		private void update(){
			//remove old SVG Elements
			Node node = svgGroup.getFirstChild();
				//This is where I think it leaks...  
				//How do I reclaim the memory when I discard this node?
				node = svgGroup.getFirstChild();


			//Put on some new elements...
			//Circle animation (it grows in radius 0->99 px)
			//Add some text
			//Rotate the scene about the center of the screen
			int rot = counter%360;
			svgGroup.setTrait("transform", "rotate("+rot+" "+(w/2)+" "+(h/2)+")");
		public void paint(Graphics g){
	        scalablegraphics.render(0,0, image);

		public void run() {
			//cause a repaint...
	    	//Keep the back light on... it takes a while 
			//(~5 minutes for it to run out of memory on the 9000 simulator) 



Posts: 484
Registered: ‎07-17-2008
My Device: Not Specified

Re: SVG Memory Leak

I have not use the SVG classes but the following lines concern me:



 //start the animation...
UiApplication.getUiApplication().invokeLater(this, 50, true);

 Isn't there some kind of SVG animation class you can use?



//Keep the back light on... it takes a while 
//(~5 minutes for it to run out of memory on the 9000 simulator) 


I don't know if this is just part of your example, but I can't imagine calling the backlight every 50 milliseconds is good for performance.


Posts: 18
Registered: ‎11-12-2009
My Device: Bold 9000

Re: SVG Memory Leak

[ Edited ]

Both are valid points, and are only in this code as a simple means to aggravate the situation.  


In my apps I have separate low priority threads for BackLight control, and for monitoring the dirty state of the screen.  The invoke every 50 is a quick hack to drive the leak.



Posts: 18
Registered: ‎11-12-2009
My Device: Bold 9000

Re: SVG Memory Leak

FYI -  I found a method to recover the memory of a removed node... remove all references to the parent doc and image.  Or rather, create a brand new DOM and throw away the old one.  Churn within a single doc will leak until it fails... if you have to remove something from your SVG doc, then it is best to recreate it from scratch without the thing you want deleted.


Not ideal, much slower, but it won't leak.