Solved

Bug in JTextPane ??

Posted on 2003-10-28
4
901 Views
Last Modified: 2008-02-01
Hi,

I am facing huge memory leak problems with JTextArea/JTextPane. After considerable investigation, I found out that the Document associated with the component is not being GC'ed properly. I ran OptimizeIt and found out that the memory is being consumed by the JTextPane.setText() method. I have implmented a HTML viewer to display large amounts of HTML data and it is leaking memory like crazy on each successive execution. Any thoughts ??

JDK1.4.2_01, WinXP

Here is the code fragment:

public class ReportViewer extends BaseFrame implements FontChange_int
{
      private      String            cReport;            
      private boolean            testMode = false;      

      // Graphical components
      private      BorderLayout      cMainLayout;
      private      JButton            cClose;
      private      JTextPane      cRptPane;
      private      Button            cClose2;

      private ViewUpdater     cViewUpdater = null;

      // Constants
      final      static      int      startupXSize = 650;
      final      static      int      startupYSize = 500;

      // Methods
      public ReportViewer(String report, ReportMain main)
      {
            // BaseFrame extends JFrame
            super("Reports Viewer", true, startupXSize, startupYSize);
            testMode     = false;
            cReport      = report;
            cViewUpdater = new ViewUpdater();
            initialize();
      }

      public void initialize()
      {
            // Create main layout manager
            cMainLayout = new BorderLayout();
            getContentPane().setLayout(cMainLayout);

            // Quick button bar - print, export, save as
            JToolBar      topPanel = new JToolBar();
            topPanel.setBorder(new BevelBorder(BevelBorder.RAISED) );
            java.net.URL      url;

            topPanel.add(Box.createHorizontalStrut(10));

            url = Scm.class.getResource("images/Exit.gif");
            cClose = new Button(new ImageIcon(url), true);
            cClose.setToolTipText("Close Window");
            topPanel.add(cClose);
            getContentPane().add(topPanel, BorderLayout.NORTH);

            // Main view window - HTML
            cRptPane = new JTextPane();
            cRptPane.setContentType("text/html");
            cRptPane.setEditable(false);

            JScrollPane sp = new JScrollPane(cRptPane);
            getContentPane().add(sp, BorderLayout.CENTER);

            // Main button - Close
            JPanel      bottomPanel = new JPanel();
            url = Scm.class.getResource("images/Exit.gif");
            cClose2 = new Button(new ImageIcon(url), "Close");
            bottomPanel.add(cClose2);
            getContentPane().add(bottomPanel, BorderLayout.SOUTH);

            cClose.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        closeWindow();
                  }
            });
            cClose2.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        closeWindow();
                  }
            });

            show();
            cViewUpdater.setText(cReport);
            SwingUtilities.invokeLater(cViewUpdater);
      }


      protected void
      closeWindow()
      {
            super.closeWindow();

            // If I add the following lines, the GC reclaims
                // part of the memory but does not flush out the text
                // component as a whole
            
            /*Document doc = cRptPane.getDocument();
            try
            {
                  doc.remove(0,doc.getLength());
            }
            catch(Exception e) {;}
            doc=null; */
            
            cRptPane=null;
            cReport = null;
            cViewUpdater = null;
            dispose();
      }

      private class ViewUpdater implements Runnable
      {
            private String cText = null;

            public ViewUpdater() {;}

            public void
            setText(String text) {
                  cText = text;
            }
            
            public void
            run() {
                  cRptPane.setText(cText);
                  cRptPane.setCaretPosition(0);
                  cText = null;
            }
      }

      // Local main - for testing
      public static void main(String args[])
      {
            //new ReportViewer(str,comp);
      }
}


--
Sudarshan
www.spectrumscm.com

0
Comment
Question by:snraghav
  • 2
4 Comments
 
LVL 35

Expert Comment

by:TimYates
ID: 9634676
> I ran OptimizeIt and found out that the memory is being consumed by the JTextPane.setText() method

Does the memory never get GCed?

How many references to this bit of memory does OptimizeIt say you have?

Do you run out of memory?
0
 

Author Comment

by:snraghav
ID: 9635563
Nope the memory never gets GCed and grows linearly on each successive execution. OptimizeIt reports that a large number of Object[] and ints are being created by the JTextPane.setText() method. More detailed investigation revealed that the objects are being created by the DefaultStyledDocument's ElementBuffer.insert() method. For some reason, the Document and its contents are sticky even if I null out all the references. I even tried trapping the Document events by writing my own listener and unregistering the listener upon close, but it doesn't seem to help.

--
Sudarshan
0
 
LVL 3

Accepted Solution

by:
savalou earned 50 total points
ID: 9637268
The javadocs for JEditorPane (superclass of JTextPane) says:
"This is implemented to remove the contents of the current document, and replace them by parsing the given string using the current EditorKit. This gives the semantics of the superclass by not changing out the model, while supporting the content type currently set on this component. The assumption is that the previous content is relatively small, and that the previous content doesn't have side effects. Both of those assumptions can be violated and cause undesirable results. To avoid this, create a new document, getEditorKit().createDefaultDocument(), and replace the existing Document with the new one. You are then assured the previous Document won't have any lingering state. "

So it doesn't look like the Document object ever gets destroyed (WAD).  Can you try to implement the above suggestion?
0
 

Author Comment

by:snraghav
ID: 9637656
savalou,

It is a decent workaround. I found out that this has been an open bug with Sun since 1999 !! The solution still leaks about 70kb for each successive execution (maybe the newly created document is sticky) but I can live with it. 70kb is much better than the 10 Mb I was previously leaking :-)

Thanks a ton ...

Sudarshan
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
simple java question 3 59
Error in @AspectJ Based AOP with Spring 2 18
spring jars download 1 35
Convert from a json string array to a Java object 3 53
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question