Threaded View

  1. #1
    Sencha User
    Join Date
    Jan 2013
    Posts
    3
    Vote Rating
    0
    TomH is on a distinguished road

      0  

    Default Answered: Need help with memory leak

    Answered: Need help with memory leak


    Hi everyone!

    I'm relatively new to GWT/GXT development. I'm trying to figure out why my application's memory consumption on the client side is increasing whenever I dynamically create panels.

    I set up a minimal example to find out what's wrong:

    Code:
    public class EP implements EntryPoint {
    
        PropPanel props;
        
        @Override
        public void onModuleLoad() {        
            RootPanel rp = RootPanel.get();
        
            Viewport topPanel = new Viewport();
            topPanel.setEnableScroll(false);
            
            
            final BorderLayoutContainer panel = new BorderLayoutContainer();
            topPanel.setWidget(panel);
            
            
            TextButton b = new TextButton("Reload");
            
            final Viewport scroll = new Viewport();    
            scroll.setEnableScroll(true);
    
            b.addSelectHandler(new SelectHandler() {
                
                @Override
                public void onSelect(SelectEvent event) {
                    if (props!=null) {
                        scroll.remove(props);
                    }
                    props = new PropPanel();
                    scroll.setWidget(props);
                }
            });        
            
            panel.setNorthWidget(b);
            panel.setCenterWidget(scroll);
            rp.add(topPanel);        
        }
    
    }
    
    public class PropPanel implements IsWidget{
    
        static int counter = 0;
        
        private FlowLayoutContainer panel;
        
        public PropPanel() {
            
            panel = new FlowLayoutContainer();
            
            for (int i=0; i<1000; i++) {
                TextButton b = new TextButton("TestButton "+counter);
                b.addSelectHandler(new SelectHandler() {
                                
                    @Override
                    public void onSelect(SelectEvent event) {
                        MessageBox mb = new MessageBox("Hallo");
                        mb.show();
                    }
                });
                            
                panel.add(b);
            }
            
            counter++;
        }
        
        @Override
        public Widget asWidget() {
            return panel;
        }
    
    }
    This app has a button labeled "Reload" and a widget "PropPanel" which is a FlowLayoutContainer that contains 1000 buttons. Now when the user hits the "Reload" button, the PropPanel removed and replaced by a new one created from scratch.

    I used Chrome's developer tools to examine what happens when the new PropPanel is replaced. It seems that there are still references to the old panel dangling around somewhere, as there are way more objects created than deleted:

    memleaktest-gxt.jpg


    I've recreated the same example using plain GWT only, to see if it is a general GWT problem:

    Code:
    public class EP implements EntryPoint {
    
        PropPanel props;
        
        @Override
        public void onModuleLoad() {
            
            RootPanel rp = RootPanel.get();
        
            final DockPanel panel = new DockPanel();
            Button b = new Button("Reload");
            
            final ScrollPanel scroll = new ScrollPanel();
            
            
            b.addClickHandler(new ClickHandler() {
                
                @Override
                public void onClick(ClickEvent event) {
                    if (props!=null) {
                        scroll.remove(props);
                    }
                    props = new PropPanel();
                    scroll.setWidget(props);
                }
            });
            
            panel.add(b, DockPanel.NORTH);
            panel.add(scroll, DockPanel.SOUTH);
            
            rp.add(panel);
        }
        
    }
    
    public class PropPanel implements IsWidget {
    
        static int counter = 0;
        
        private FlowPanel panel;
        
        public PropPanel() {
            
            panel = new FlowPanel();
            
            for (int i=0; i<1000; i++) {
                Button b = new Button("TestButton "+counter);
                b.addClickHandler(new ClickHandler() {
                    
                    @Override
                    public void onClick(ClickEvent event) {
                        Window.alert("Hallo");
                    }
                });
                
                panel.add(b);
            }
            
            counter++;
        }
        
        
        @Override
        public Widget asWidget() {                
            
            return panel;
        }
    
    }
    However, when running the plain GWT example, everything seems to be collected fine:

    memleaktest-gwt.jpg


    All the tests were done using compiled code (not hosted mode).

    Did I forget something in my GXT code or is this general problem with GXT widgets that are created on the fly? I hope someone of you guys can help me.

    Thanks in advance!
    Tom

  2. Thanks for the clarification - in GXT 3.0.1, Container.widgetMap was keeping old references that it should have disposed of - this is fixed in later revisions, including GXT 3.0.3.

    GXT 3.0.3 is currently available for support subscribers only. I do not know when it will be generally available.

Thread Participants: 1

Tags for this Thread