I am struggling with a nasty problem for many days now. In my Java Swing application, I use two JTextPane
s extended with Syntax Highlighting for XML-Text as described in this example with some little changes:
XML Syntax Highlighting in JTextPanes
These two JTextPane
s are placed in two JScollPane
s 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 XmlTextPane
s. 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 TextPane
s).
The strange thing is that even resetting the TextPane
s and/or removing them (or disposing the Frame
that holds the Component
s) 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:
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 TextPane
s 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?
Don't worry. It's not memory leak.
The ImageCache
is based on SoftReference
s. 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.