java - 使用 JTextPane 时如何防止内存泄漏?
问题描述
我有一个JFrame
包含一个按钮。单击该按钮时,它会打开一个包含JTextPane
大量文本的窗口。
- 开始时,应用程序占用 35 mb 内存。
- 打开新窗口时,应用程序会占用大约 200 mb 的内存。
- 当新窗口关闭时,应用程序会占用大约 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 来测试这个,我看到任务管理器上的内存使用情况
解决方案
不要指望 System.gc() 会强制执行 gc。一些 jvm 在被调用时甚至什么都不做。jvm 可以在它决定时执行 gc。
推荐阅读
- arkit - 如何在 Swift 4.2 中使用 ARFaceTracking 获得面部网格中的点,如眼睛、眉毛、嘴唇、嘴巴、鼻子?
- scala - 具有多态类型的有限状态机?
- google-apps-script - 如何构建指向 Google 日历活动的链接?
- c# - Autofac - 注册交易
- javascript - 是否可以将 JavaScript 字符串设置为对象点表示法的访问器属性?
- python - 如何在卫星图像中使用高斯核来改变图像的分辨率
- jquery - 导出到 Excel 时将 jQGrid 数字转换为文本
- python - 使用远程服务器开发和调试 Python
- sql - 如果我们在连接查询中切换表的位置会增加加载数据的速度,这是真的吗?
- android - 针对 SMS 和 CALL_LOG 的 Google 权限限制