S
Sudarshan Raghavan
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. Detailed analysis showed that a large number of Object[] and
ints are being created by the DefaultStyledDocument's
ElementBuffer.insert() method and it is never reclaimed. I have
implmented a HTML viewer to display large amounts of HTML data and it
is leaking memory like crazy on each successive
execution.
I was surprised to find that this has existed as a bug in Swing since
1999 !! But I wanted to find out if there is a decent workaround to
the problem.
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);
}
}
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. Detailed analysis showed that a large number of Object[] and
ints are being created by the DefaultStyledDocument's
ElementBuffer.insert() method and it is never reclaimed. I have
implmented a HTML viewer to display large amounts of HTML data and it
is leaking memory like crazy on each successive
execution.
I was surprised to find that this has existed as a bug in Swing since
1999 !! But I wanted to find out if there is a decent workaround to
the problem.
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);
}
}