Search code examples
javawindowsswingmemory-leaksjtextpane

Using Java Swing SystemLookAndFeel on Windows machines leads to MemoryLeaks in CachedPainter with JTextPanes


I am struggling with a nasty problem for many days now. In my Java Swing application, I use two JTextPanes extended with Syntax Highlighting for XML-Text as described in this example with some little changes: XML Syntax Highlighting in JTextPanes

These two JTextPanes are placed in two JScollPanes in a JSplitPane that is placed directly in the ContentPane of a JFrame. The first TextPane is editable (like a simple XML-Request-Editor), the second TextPane displays XML-Responses from my server backend.

Everything works as expected as long as I don't try to put "many lines" in those XmlTextPanes. This results in a pretty fast increase of memory used (going from < 100 MB to 1,000 MB after just a few lines inserted to one or both of the TextPanes).

The strange thing is that even resetting the TextPanes and/or removing them (or disposing the Frame that holds the Components) will not change the memory used at all! Forcing a garbage collection won't change anything, too. Something must still be holding references to the allocated stuff....

In order to see what exactly is consuming all that memory I tried to analyze the application with the Eclipse MATS resulting in this: Eclipse MATS Results

This clearly shows that the CachedPainter is holding a lot of stuff... Asking Google it seems that I am not the only one having memory issues with the CachePainter but I was unable to find a reason - and even more important - and solution for this.

After messing around with this for many many hours now I found out that this problem does not occur when I set my application to use

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

instead of

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

With the cross platform Look and Feel, I was able to put thousands of lines of XML content in my TextPanes without getting over 200 MB memory used. With the same code but set to platform Look and Feel (Windows 7), I reach over 2k MB memory usage after ~200 lines

I can reproduce this behavior compiling against JDK7 and JDK8 :(.

What is causing this and how can I fix it?

€dit: Some additional Informations: on further research it seems like some LAFs have problems with d3d buffers. This int[] in the MATS screenshot could be some kind of rendering buffer, too pointing in the same possible direction.... My application already sets this in order to prevent some rendering performance issues (frame resizing for example!):

System.setProperty("sun.java2d.noddraw", Boolean.TRUE.toString());

I could try to add this flag to the startparameters, too:

-Dsun.java2d.d3d=false

Or do you think that this won't help?


Solution

  • Don't worry. It's not memory leak.

    The ImageCache is based on SoftReferences. From the sources

    public class ImageCache {
        private int maxCount;
        private final LinkedList<SoftReference<ImageCache.Entry>> entries;
        ....
    

    From Javadoc

    All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError.

    So when you have not enough memory, the cache is cleared to free enough memory.