Results 1 to 5 of 5

Thread: Memory consumption with swing apps

  1. #1
    Join Date
    Sep 2004
    Location
    France
    Posts
    44

    Default Memory consumption with swing apps

    Hi

    I am using spring to wire my swing application but I have some problems with the memory footprint of my app.

    So I did some tests to see what can be the spring part in this footprint. I have some really weird results so I want to submit them to you.

    I've attached a simple test project. I have two different tests :
    • First I create 60 simple beans directly in java or with Spring
    • Second I create 60 panels directly in java or with Spring

    In my first test the memory footprint of both cases is nearly the same : 800 ko.
    In my second test, the memory footprint of the java test is also 800 ko.
    But with Spring, in this second test the memory footprint in 8 Mo !

    Does somebody have any explanation ? What's special with JPanel ? Is Spring memory consumption linked with the number of methods in the wired class (JPanel has a lot of methods) ? Can I do something to reduce this footprint ?

    The project attached is a simple maven project. If you have maven installed just run 'mvn test' to see the results : the result values are :
    1. Test without spring on JPanel
    2. Test with Spring on JPanel
    3. Test without spring on simple beans
    4. Test with Spring on simple beans
    Attached Files Attached Files

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,425

    Default

    The tests aren't the same though. The non-panel one lazy inits all the beans, the other doesn't. There are also more beans in the JPanel example. I guess the increase in memory is also more than likely the fact that JPanel is doing a lot more than your simple test classes are.
    Last edited by karldmoore; Feb 9th, 2007 at 07:39 AM.

  3. #3
    Join Date
    Sep 2004
    Location
    France
    Posts
    44

    Default

    Sorry but the comparison is between two tests that creates exactly the same number of panels. The other test was juste here to show that the problem only applies for panels, not for simple beans

    We are dying a little bit more inside Spring with YourKit profiler and it seems that the difference is due to MethodInterceptor cache that is hold by CachedIntrospectionResults.

    Here is a simpler test you can launch (you have to recreeate a new CachedIntrospectionResults class because the Spring one is private). You will see that there is 6x more memory consumes with CachedIntrospectionResults : I don't know why.

    Code:
    import java.beans.Introspector;
    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryMXBean;
    
    import javax.swing.JPanel;
    
    import junit.framework.TestCase;
    
    public class LaunchContextTest extends TestCase
    {
        private static final MemoryMXBean MEMORY_BEAN = ManagementFactory.getMemoryMXBean();
        public void testJPanel()
        {
            MEMORY_BEAN.gc();
            long memStart = MEMORY_BEAN.getHeapMemoryUsage().getUsed();
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            CachedIntrospectionResults.forClass(new JPanel() {}.getClass());
            long memStop = MEMORY_BEAN.getHeapMemoryUsage().getUsed();
            System.out.println("Test avec CachedIntrospectionResults sur beans simples : " + (memStop - memStart));
        }
        
        
        public void testIntrospector() throws Exception
        {
            MEMORY_BEAN.gc();
            long memStart = MEMORY_BEAN.getHeapMemoryUsage().getUsed();
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            Introspector.getBeanInfo(new JPanel() {}.getClass());
            long memStop = MEMORY_BEAN.getHeapMemoryUsage().getUsed();
            System.out.println("Test avec Introspector sur beans simples : " + (memStop - memStart));
        }
    }

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,425

    Default

    Quote Originally Posted by scesbron View Post
    Sorry but the comparison is between two tests that creates exactly the same number of panels. The other test was juste here to show that the problem only applies for panels, not for simple beans
    Apologies. I didn't see the other tests, that's why I was slightly confused. I've put my glasses on and I can see them now . I don't really know enough about this to comment, anyone else.

  5. #5
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    CacheIntrospectionResults caches the PropertyDescriptors, so its memory footprint would be to some degree proportional to the number of properties on classes being cached.

    On the other hand though, all the cache instances are only weakly referenced, so it doesn't really become a memory consumption issue, unless your application is an applet or something.
    --Jing Xue

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •