snraghav
asked on
Bug in JTextPane ??
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 (cMainLayo ut);
// Quick button bar - print, export, save as
JToolBar topPanel = new JToolBar();
topPanel.setBorder(new BevelBorder(BevelBorder.RA ISED) );
java.net.URL url;
topPanel.add(Box.createHor izontalStr ut(10));
url = Scm.class.getResource("ima ges/Exit.g if");
cClose = new Button(new ImageIcon(url), true);
cClose.setToolTipText("Clo se Window");
topPanel.add(cClose);
getContentPane().add(topPa nel, BorderLayout.NORTH);
// Main view window - HTML
cRptPane = new JTextPane();
cRptPane.setContentType("t ext/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("ima ges/Exit.g if");
cClose2 = new Button(new ImageIcon(url), "Close");
bottomPanel.add(cClose2);
getContentPane().add(botto mPanel, BorderLayout.SOUTH);
cClose.addActionListener(n ew ActionListener() {
public void actionPerformed(ActionEven t e) {
closeWindow();
}
});
cClose2.addActionListener( new ActionListener() {
public void actionPerformed(ActionEven t e) {
closeWindow();
}
});
show();
cViewUpdater.setText(cRepo rt);
SwingUtilities.invokeLater (cViewUpda ter);
}
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
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
// Quick button bar - print, export, save as
JToolBar topPanel = new JToolBar();
topPanel.setBorder(new BevelBorder(BevelBorder.RA
java.net.URL url;
topPanel.add(Box.createHor
url = Scm.class.getResource("ima
cClose = new Button(new ImageIcon(url), true);
cClose.setToolTipText("Clo
topPanel.add(cClose);
getContentPane().add(topPa
// Main view window - HTML
cRptPane = new JTextPane();
cRptPane.setContentType("t
cRptPane.setEditable(false
JScrollPane sp = new JScrollPane(cRptPane);
getContentPane().add(sp, BorderLayout.CENTER);
// Main button - Close
JPanel bottomPanel = new JPanel();
url = Scm.class.getResource("ima
cClose2 = new Button(new ImageIcon(url), "Close");
bottomPanel.add(cClose2);
getContentPane().add(botto
cClose.addActionListener(n
public void actionPerformed(ActionEven
closeWindow();
}
});
cClose2.addActionListener(
public void actionPerformed(ActionEven
closeWindow();
}
});
show();
cViewUpdater.setText(cRepo
SwingUtilities.invokeLater
}
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(
cText = null;
}
}
// Local main - for testing
public static void main(String args[])
{
//new ReportViewer(str,comp);
}
}
--
Sudarshan
www.spectrumscm.com
ASKER
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
--
Sudarshan
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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
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?