首页 > 解决方案 > 使用 JTextPane 时如何防止内存泄漏?

问题描述

我有一个JFrame包含一个按钮。单击该按钮时,它会打开一个包含JTextPane大量文本的窗口。

  1. 开始时,应用程序占用 35 mb 内存。
  2. 打开新窗口时,应用程序会占用大约 200 mb 的内存。
  3. 当新窗口关闭时,应用程序会占用大约 120 mb 的内存。
package main;

import javax.swing.*;
import java.awt.*;

public class MemoryLeakTest {
    public void start(){
        JFrame frame = new JFrame();
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        JButton button = new JButton("Create new window");
        button.addActionListener(l->{
            createWindow();
        });
        frame.add(button);
        frame.setVisible(true);
    }
    public void createWindow(){
        window w = new window();
        w.setVisible(true);
    }
    public static void main(String[] args) {
        new MemoryLeakTest().start();
    }
}

class window extends JFrame {
    private JTextPane textPane;

    public window() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(500, 500);
        textPane = new JTextPane();
        textPane.setText(extremelyLongText());
        add(textPane);
        System.out.println("New window created!");
    }

    public String extremelyLongText() {
        StringBuilder builder = new StringBuilder();
        for (int j = 0; j < 1000; j++, builder.append("\n"))
            for (int i = 0; i < 10000; i++, builder.append("a")) ;
        return new String(builder);
    }

    @Override
    public void dispose() {
        super.dispose();
        textPane.setText("");
        System.gc();
        textPane= null;
        System.gc();
    }
}

我已经覆盖了 dispose 方法以将其设置JTextPane为 null。我预计内存消耗会回落到 35 mb,但它下降到只有 120 mb。为什么会这样?JTextPane没有收集垃圾的字符串吗?每当我使用 a 时,如何确保释放内存JTextPane

编辑:我在 Windows 10 上使用 jdk 16 来测试这个,我看到任务管理器上的内存使用情况

标签: javaswinguser-interfacememory-managementmemory-leaks

解决方案


不要指望 System.gc() 会强制执行 gc。一些 jvm 在被调用时甚至什么都不做。jvm 可以在它决定时执行 gc。


推荐阅读