1

所以今天我打开任务管理器,看到我的应用程序每秒泄漏 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);
}

而且我似乎无法弄清楚为什么它不断泄漏内存?对此内存泄漏的任何提示或解决方案都会有所帮助!

问候,坦布尔

4

3 回答 3

2

看这部分程序:

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

问题:thread == curThread我标记为“这里”时会发生什么?

答:没错。

问题:循环会终止吗?

回答:不!


老实说,这部分代码是一团糟。您似乎正在使用两种或三种不同的机制来试图杀死……某物。最后,您调用SwingUtilities.invokeLater(this)which 将(我认为)只是启动另一个线程以再次运行 Runnable。只是……难以理解。

于 2013-05-20T13:44:20.107 回答
2

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

SwingUtilities.invokeLater()在 EDT 上运行 Runnable。如果该 runnable 永远不会返回,就像你在这里的一样,那么就无法处理更多事件)

于 2013-05-20T14:04:39.023 回答
1

出来这些行之后:

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

内存泄漏似乎被堵住了。为什么 setText() 会泄漏内存?问题有点回答了,但为什么?

于 2013-05-20T13:49:22.970 回答