JFrame泄漏内存?

时间:2013-05-20 13:33:25

标签: java swing memory-leaks thread-sleep invokelater

所以今天我打开了任务管理器,看到我的应用程序每秒泄漏200kbs的内存。我看着我的主循环:

public final void run() {
    try {
        Thread.sleep(27);
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }

    Thread curThread = Thread.currentThread();
    long lastLoopTime = System.nanoTime();
    long OPTIMAL_TIME = 1000000000 / FPS;
    int fps = 0;
    long lastFpsTime = 0;

    while (thread == curThread) {
        if (shouldClose)
        {
            running = false;
            frame.dispose();
            thread = null;
            curThread.interrupt();
            curThread = null;
        }

        long now = System.nanoTime();
        long updateLength = now - lastLoopTime;
        lastLoopTime = now;
        //double delta = updateLength / ((double)OPTIMAL_TIME);

        lastFpsTime += updateLength;
        fps++;

        if (lastFpsTime >= 1000000000) {
            System.out.println("FPS: " + fps + "");
            fpsLabel.setText("FPS: " + fps);
            lastFpsTime = 0;
            fps = 0;
        }

        if (GuiNewProject.createButton.isEnabled() && createProjectDialogIsOpen)
            if (GuiNewProject.folder.getText().length() == 0 || GuiNewProject.projectName.getText().length() == 0)
                GuiNewProject.createButton.setEnabled(false);

        if (!(GuiNewProject.createButton.isEnabled()) && createProjectDialogIsOpen)
            if (GuiNewProject.folder.getText().length() > 0 && GuiNewProject.projectName.getText().length() > 0)
                GuiNewProject.createButton.setEnabled(true);

        //render();
        fpsDone.setText("FPS: " + fps);

        try {
            if (shouldClose) {
                return;
            }
            else
            {
                Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    SwingUtilities.invokeLater(this);
}

我似乎无法弄清楚为什么它会一直泄漏记忆? 任何有关此内存泄漏的提示或解决方案都会有所帮助!

此致 坦布雷

3 个答案:

答案 0 :(得分:2)

看看这部分程序:

 while (thread == curThread) {
    if (shouldClose)
    {
        running = false;
        frame.dispose();
        thread = null;
        curThread.interrupt();
        curThread = null;
        // HERE
    }
    // ...
 }

问题:thread == curThread在我标记为“HERE”的位置会是什么?

答案:是的。

问题:循环会终止吗?

答案:不!


说实话,这段代码很乱。你似乎正在使用两种或三种不同的机制来试图杀死某些东西。最后,你调用SwingUtilities.invokeLater(this),我会认为只是启动另一个线程来再次运行Runnable。这只是......难以理解。

答案 1 :(得分:2)

JLabel.setText()调用repaint,将PaintEvent推送到事件队列。因为你的循环停止了事件队列,它会无限增长。因此内存泄漏。

SwingUtilities.invokeLater()在EDT上运行Runnable。如果那个runnable永远不会返回,就像你的那样,那么就不会再处理其他事件了)

答案 2 :(得分:1)

在表达出这些界限之后:

fpsLabel.setText("FPS: " + fps);
fpsDone.setText("FPS: " + fps);

内存泄漏似乎堵塞了。 为什么setText()泄漏内存? 问题有点回答,但仍然是为什么?