Announcement Announcement Module
Collapse
No announcement yet.
Memory consumption with swing apps Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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

  • #2
    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, 08:39 AM.

    Comment


    • #3
      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));
          }
      }

      Comment


      • #4
        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.

        Comment


        • #5
          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.

          Comment

          Working...
          X