Gelmiş geçmiş en büyük porno sitemiz olan 2pe de her zaman en kaliteli pornoları sunmayı hedefledik. Diğer video sitemiz olan vuam da ise hd porno ağırlıklı çalışmalara başladık.

Hybrid 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.

  3. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    I haven't read through the whole example yet, but you are on the right track chasing this in Chrome. The next step is to dig into those snapshots, and see *what* is leaking, and *why* it is leaked.

    To do this, first compile with style=PRETTY - this will tell GWT to give each method and class a readable name so you can hope to see why they are still being referenced. Then, run again, taking a snapshot after each full step (when you expect that all new buttons have been created, and all old buttons have be GC'd (or can be GC'd). Then, open the comparison panel you have in your first screenshot, and look for items where more are being created than deleted. Note the class of the object being created too many times - this is what is (probably) the source of your leak. Note that it probably doesn't matter *which* object you pick - chances are they are either all leaked together, or you've got multiple leaks

    Now, expand that class to see the instances themselves. Pick an instance, select it, and look in the Retaining Tree window. These represent the things that point *to* this object. If you are looking at a newly created object, there may be several things pointing at it, so you might need to switch to another view and see why an old instance of that same object is still getting held on to.

    Don't worry about (system), (compiled code), (array), etc - these are browser internals, and not something that your app has a lot of control over.

    One last thought - the Viewport control isn't designed to be added to anything but the RootPanel. For the same reason, you shouldn't have more than one of them. This widget always sizes itself to all of the available space in the browser - it is the thing that *other* widgets get added to in order to ensure they resize correctly. In your sample, you shouldn't need it at all.

  4. #3
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    I've just set up and run this example (the GXT version, not the GWT one) using GWT 2.4.0 and GXT 3.0.3, and cannot see any sign of a memory leak in chrome 24.

    My steps were - compile in PRETTY, run the app, click the button once, take a snapshot, click the button again, take a second snapshot. It is important to perform the operation *first* to ensure that there is actually memory to free up, before checking to see how much is freed.

    My test run shows lots of objects made and deleted:
    ArrayList_0 2995 2995
    SimpleEventBus$1_0 2002 2002
    TextButton_1 1000 1000
    etc
    But the only cases where more objects are created than deleted are the ()'d objects - browser internals, and not many of those. After the first few runs, the app had settled at increasing by approx. 0.02 MB (out of about 20mb) per reload click.

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

      0  

    Default


    Hi Colin!

    Thank you for your comments. Since you mentioned that you were using GWT 2.4 and GXT 3.0.3, I first tried re-running the tests using GWT 2.4 (I was using GWT 2.5 before). However that didn't change anything in the outcome. I'm currently using GXT 3.0.1, but I have no access to the 3.0.3 release so far.

    Then I looked into the output from the heap snapshots (I reduced the number of buttons from 1000 to 100 in order to make the output a little smaller). It seems that for every time a PropPanel is replaced with a new one, there is a detached DOM tree dangling around:

    memleak-summary.jpg

    My knowledge about how GWT/GXT work on the client side is pretty limited, so it's kinda hard for me to further investigate what exactly causes these detached DOM trees. But I suppose it must be something that was fixed between GXT release 3.0.1 and 3.0.3.

    I guess I'll have to wait until GXT 3.0.3 is released. Is there any prospective release date so far?

    Regards,
    Tom

  6. #5
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    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.

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

      0  

    Default


    Colin,

    Thanks for the answer. I just played around with the Chrome developer tools and came to the same conclusion:

    retaining_tree.jpgborderlayoutcontainer.jpg

Thread Participants: 1

Tags for this Thread