See my post earlier on memory leaks - I had trouble with Images like this in IE as well.
I suggest you try: 1) re-creating the Image every time instead of using setUrl() 2) when removing the Image, call into a purge references method like this: /** * Gratefully taken from http://javascript.crockford.com/memory/leak.html */ public native static void purge( Element d ) /*-{ var a = d.attributes, i, l, n; if (a) { l = a.length; for (i = 0; i < l; i += 1) { n = a[i].name; if (typeof d[n] === 'function') { d[n] = null; } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { purge(d.childNodes[i]); } } }-*/; 3) I do that with a special Image subclass: public class NoMemLeakImage extends Image { public NoMemLeakImage() { super(); } public NoMemLeakImage( String imageURL ) { super( imageURL ); } @Override protected void onDetach() { try { super.onDetach(); } finally { // IE7 seems to leave onabort, __kids and __cleanup pointing // into javascript & causing a circular reference here. Just // wipe everything.on detach. DOMHelpers.purge( getElement() ); // TODO: This seems a little unsafe. Specifically - if you re- attach // TODO: the image later, we don't re-set-up the event handlers. } } } Regards, Paul On Nov 1, 10:06 am, hermis <[email protected]> wrote: > Hello, > > I have written a simple application which fills a FlexTable with a set > of images. There is a timer which updates the URL of each image every > second. The URL points to a Servlet which in turn generates a random > PNG image on its doGet() method and writes it to the response output > stream. The servlet sets the "Cache-Control" header to "No-Cache". > > When I run the webapp in IE7 / 8 the memory gradually increases. > Leaving it overnight can get it close to 1Gb. > > Here is the client code: > > ################################################################# > > public class LeakyApp implements EntryPoint > { > public static final String IMAGE_SERVLET_NAME = "imageServlet"; > > public void onModuleLoad() > { > leak(); > } > > private void leak() > { > UrlBuilder urlBuilder = createUrlBuilder(); > > final FlexTable table = new FlexTable(); > > final List<Image> lstImages = createAndAddImages(5,10 ,table > ); > > final String strURL = urlBuilder.buildString(); > > final Timer timer = new Timer(){ > > int nCounter = 0; > > @Override > public void run() > { > for (Image img : lstImages) > { > img.setUrl( strURL + "?" + > nCounter++) ; > } > } > }; > > final Button btnStartLeak = new Button("Leak"); > btnStartLeak.addClickHandler( new ClickHandler() > { > @Override > public void onClick(ClickEvent event) > { > RootPanel.get().remove( btnStartLeak ); > RootPanel.get().add( table ); > timer.scheduleRepeating( 1000 ); > } > }); > > RootPanel.get().add( btnStartLeak ); > } > > private List<Image> createAndAddImages(int rowCount, int colCount, > FlexTable table) > { > List<Image> lstImages = new ArrayList<Image>(); > > for(int row = 0; row<rowCount; row++) > { > for(int col = 0; col<colCount; col++) > { > Image image = new Image(); > lstImages.add( image ); > table.setWidget(row, col, image); > } > } > > return lstImages; > } > > private UrlBuilder createUrlBuilder() > { > UrlBuilder urlBuilder = null; > > if( GWT.isScript() ) > { > urlBuilder = new UrlBuilder(); > urlBuilder.setHost( Window.Location.getHost() ); > urlBuilder.setPath( Window.Location.getPath() + > IMAGE_SERVLET_NAME ); > } > else > { > urlBuilder = Window.Location.createUrlBuilder(); > urlBuilder.setPath( IMAGE_SERVLET_NAME ); > } > > return urlBuilder; > } > > } > > ############################################################ > > Here is the servlet code: > > ############################################################ > > public class ImageServlet extends HttpServlet > { > private int nCounter = 0; > private Font font = new Font("Tahoma", Font.BOLD, 10); > > private static Color getRandomColor() > { > int r = (int)(Math.random()* 255); > int g = (int)(Math.random()* 255); > int b = (int)(Math.random()* 255); > > return new Color(r,g,b); > } > > @Override > protected void doGet ( HttpServletRequest request, > HttpServletResponse response ) throws IOException > { > > OutputStream out = response.getOutputStream(); > > response.setContentType("image/png"); > response.addHeader("Pragma", "no-cache"); > response.addHeader("Cache-Control", "no-cache"); > > ImageIO.write( generateRandomImage(), "png", out ); > > out.close(); > } > > private BufferedImage generateRandomImage() > { > return generateRandomImage(80, 80); > } > > private BufferedImage generateRandomImage(int width, int height) > { > BufferedImage image = new BufferedImage(width, height, > BufferedImage.TYPE_INT_ARGB); > > Graphics2D g2d = image.createGraphics(); > g2d.setFont( font ); > g2d.setColor( getRandomColor() ); > g2d.fillRect(0, 0, width, height); > g2d.setColor( Color.WHITE ); > g2d.drawString("" + nCounter, 20, 20); > > System.err.println(" img " + nCounter ); > > nCounter++; > > if( nCounter == Integer.MAX_VALUE ) > nCounter = 0; > > return image; > } > > } > > ############################################################ > > Is there a programming error, or is it the nature of what the > application is doing causing the memory leak? Can anyone explain what > is happening behind the scenes? > > Thanks. -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
