为什么JTable滚动占用了这么多内存?

时间:2012-01-02 15:39:01

标签: java swing components scroll jtable

您好我正在编写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进程确实使用了内存。

2 个答案:

答案 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就不容易找到工作