您好我正在编写java中的双面板文件管理器,我遇到了问题。
每当我滚动JTable
时,它需要大约8M的内存...有没有办法解决这个问题?消耗40 - 60M的内存后,每次都会停止。它是Swing
组件问题吗?
感谢您的回复。
修改
我试着理解为什么需要这么多记忆。现在我知道问题的根源。我用这个动作制作了一个小按钮:
jScrollPane1.repaint();
。
当我点击它10次时,我在任务管理器和VisualVM中都有大量的内存消耗。但是在VisualVM中,GC开始收集50 MB并将其降低到8 Mb。但Windows任务管理员仍在增加其价值。
重绘方法在Windows中造成大量内存泄漏。有什么问题吗?
EDIT2
对这个问题的进一步研究给了我这个。我试图在Linux平台上运行这个程序,没有泄漏。该程序使用了大约20 M的内存。所以我编写了一个小线程,它调用JScrollPanes
上的方法重绘。令我惊讶的是,Windows机器内存一直在上升到110M,但随后操作系统开始在内存上更加努力。
线程:
@Override
public void run() {
while (true) {
jScrollPane1.repaint();
jScrollPane2.repaint();
try {
this.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
我正在进行正常的复制/重命名/删除操作,也是在没有内存上升的目录中进行的。我注意到内存也减少到99M。
在监控线程上:
@Override
public void run() {
while (true) {
aLabel.setText("Memory consumption: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
try {
this.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
数字从8M到50M再到8M。垃圾收集成功了。那么真正的问题是Windows平台还是JVM的兼容性? 由于trashgod认为任务管理器在获取内存消耗方面并不准确,但java进程确实使用了内存。
答案 0 :(得分:1)
重复调用FileSystemView.getFileSystemView()
可能会出现问题,如建议here和个性化here。编辑您的问题以包含展示问题的sscce可能会有所帮助。使用分析器可能会提出问题的范围和严重性;可能已经安装了Java VisualVM。
Windows任务管理器仍在增加其价值。
Windows任务管理器可能不完全是决定性的,如建议的here。在这种情况下,jvisualvm
结果可能更可靠。
答案 1 :(得分:0)
在EDT期间永远不要使用Thread#sleep
,这就是为什么你得到un_expecting UsedMemory
,
1)Swing GUI是单线程的
2)Swing GUI等待所有已完成的事件,所有更改都会在一瞬间完成,包括使用Thread#sleep
,
3)通过使用Thread#sleep
,您可以模拟并在屏幕上看到未经预期的GUI重绘,或者值未刷新或重新绘制
4)您遇到Concurency in Swing
的问题 5)我看不出在那里使用repaint()
的任何理由,请注意本地环境非常难的方法
6)使用并将代码包装到
7)因为我需要一些方法(故意)使用Thread#sleep
,如果没有Controler覆盖整个EDT就不容易找到工作