JDK-4257720 : Swing styled text application using excessive memory
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: unknown
  • Submitted: 1999-07-28
  • Updated: 2000-03-22
  • Resolved: 2000-03-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.0 betaFixed
Related Reports
Relates :  
Description
When using the Swing demo application Stylepad (as a reproducable test case) you can observe excessive memory usage, making the application not viable as a release product.  Reproduce by the following:
(NT 4 SP4, JDK 1.2.2 FCS)
i) open task manager
ii) run Stylepad application
iii) cut all of alice text out 
iv) copy some 96k text from ie. Notepad
v) paste using menu 

You can see that over 20MB is taken up by this procedure and it is linear upon pasting greater text sizes.

I believe this to be associated with bug : 4203912.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: kestrel FIXED IN: merlin-beta INTEGRATED IN: merlin-beta
14-06-2004

EVALUATION Using OptimizeIt to analyze the memory consumption of models and views produced by StyledEditorKit (which Stylepad uses) show that about 13% of the memory consumed is from the model and the other 87% is the view. Switching to use ZoneView to hold the paragraphs would bring the consumption for views to a constant amount of something just a little over what the model consumes (13% in the analysis performed). Using weak references and sharing position objects that point to the same location could further reduce the consumption of the model. It also looks like there might be a leak in GapContent. The StyledEditorKit now uses ZoneView which has been substantially improved to the point that it is believed to be a reasonable replacement. The test below was used to measure the heap before and after which is not an accurate measurement (i.e. the acutal consumption would be less), but it does give an approximation. A 1Mb file was used for the test. The kestrel version loaded in 47 sec and reported 42Mb The post-fix version loaded in 5.8 sec and reported 12Mb The test used was: import java.io.*; import java.awt.*; import javax.swing.*; public class StyleTest { public static void main(String[] args) { try { // initialize a JEditorPane and prepare to load it using // setText() which will run synchronously. JEditorPane testPane = new JTextPane(); JScrollPane scroller = new JScrollPane(); JViewport vp = scroller.getViewport(); vp.add(testPane); vp.setBackingStoreEnabled(true); JFrame frame = new JFrame(); frame.setTitle("JEditorPane test of text/styled"); frame.setBackground(Color.lightGray); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add("Center", scroller); frame.pack(); frame.setSize(600, 480); frame.show(); // String text = readFile(); long startingMemoryUse = getUsedMemory(); System.err.println("starting test"); long startTime = System.currentTimeMillis(); FileReader fr = new FileReader("large.txt"); testPane.read(fr, null); // testPane.setText(text); long endTime = System.currentTimeMillis(); System.err.println("test done"); long endingMemoryUse = getUsedMemory(); float approxSize = (endingMemoryUse - startingMemoryUse); System.err.println("loaded in: " + (endTime - startTime) + " ms"); System.err.println("heap difference: " + approxSize); } catch (Throwable e) { e.printStackTrace(); System.exit(1); } System.exit(0); } private static String readFile() throws FileNotFoundException { System.out.println("creating 1Mb string"); File f = new File("large.txt"); FileReader fr = new FileReader(f); StringBuffer r = new StringBuffer("");; char[] buff = new char[4096]; int nch; try { while ((nch = fr.read(buff, 0, buff.length)) != -1) { r.append(buff); } } catch(IOException e) { e.printStackTrace(); System.exit(1); } System.out.println("done creating 1Mb string"); return r.toString(); } private static long getUsedMemory() { gc(); long totalMemory = Runtime.getRuntime().totalMemory(); gc(); long freeMemory = Runtime.getRuntime().freeMemory(); long usedMemory = totalMemory - freeMemory; return usedMemory; } private static void gc() { try { System.gc(); Thread.currentThread().sleep(100); System.runFinalization(); Thread.currentThread().sleep(100); System.gc(); Thread.currentThread().sleep(100); System.runFinalization(); Thread.currentThread().sleep(100); } catch (Exception e) { e.printStackTrace(); } } } timothy.prinzing@eng 2000-03-17
17-03-2000