使用swing JTextPane进行大量内存泄漏

时间:2018-01-24 14:40:06

标签: java swing memory-leaks jtextpane

我正在尝试使用JTextPane在swing中实现消息控制台。我发现了一些实现,但遇到了大量的内存泄漏。

II进行了大量研究并确保(至少我希望我这样做)遵循AWT线程规则。我无法弄清楚我做错了什么...... 这包括彻底阅读看似相似的案例:

How to prevent memory leak in JTextPane.setCaretPosition(int)?

下面是再现泄漏的简单示例:在摆动(500毫秒重复)计时器中,添加了100行文本。只要有10000行,就会删除1000行。

请帮助解决这个问题

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class ConsoleTester {
    private int m_totalRowsNum = 0;
    StyledDocument m_document;
    String lineText = "ONCE upon a time there were four little Rabbits, and their names were— Flopsy, Mopsy, Cotton-tail, \n";
    Style styleGreen;
    private int m_docLength = 0;

    void createAndShowGUI() {
        JFrame frame;
        JTextPane textPane;
        JTextField textField;
        JScrollPane scrollPane;

        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textPane = new JTextPane();
        textPane.setEditable(false);
        textPane.setFont(new Font("Courier New", Font.PLAIN, 16));
        textPane.setOpaque(false);
        m_document = textPane.getStyledDocument();

        styleGreen = textPane.addStyle("styleGreen", null);
        StyleConstants.setForeground(styleGreen, Color.green);
        StyleConstants.setBold(styleGreen, true);

        textField = new JTextField();

        scrollPane = new JScrollPane(textPane);
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        frame.add(textField, BorderLayout.SOUTH);
        frame.add(scrollPane, BorderLayout.CENTER);

        frame.getContentPane().setBackground(new Color(50, 50, 50));
        frame.setSize(660, 350);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        javax.swing.Timer timer = new Timer(500, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("document length: " + m_docLength + " m_totalRowsNum: " + m_totalRowsNum);
                for (int i = 0; i < 100; i++) {
                    AddLine();
                }
                textPane.setCaretPosition(m_document.getLength());
            }
        });
        timer.start();
    }

    private void AddLine() {
        m_totalRowsNum++;
        try {
            if (m_totalRowsNum % 10000 == 0) {
                m_document.remove(0, 100000);
                m_docLength -= 100000;
            }
            m_document.insertString(m_docLength, lineText, styleGreen);
            m_docLength += lineText.length();
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ConsoleTester().createAndShowGUI();
            }
        });
    }
}

0 个答案:

没有答案