Frage

So today I opened Task Manager and saw that my application leaks 200kbs of memory every second. I looked at my main loop:

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);
}

And I can't seem to figure out why it keeps leaking memory? Any hints or solution to this memory leak would be helpful!

Regards, tambre

War es hilfreich?

Lösung

JLabel.setText() calls repaint, which pushes a PaintEvent onto the event queue. Because your loop is stalling the event queue, it grows infinitely. Hence the memory leak.

(SwingUtilities.invokeLater() runs a Runnable on the EDT. If that runnable never returns, like yours here, then no further events can be processed)

Andere Tipps

Look at this part of the program:

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

Question: What will thread == curThread be at the point I labeled "HERE"?

Answer: True.

Question: And will the loop terminate?

Answer: No!


To be brutally honest, this part of your code is a mess. You seem to be using two or three different mechanisms to attempt to kill ... something. Finally, you call SwingUtilities.invokeLater(this) which will (I think) just launch another thread to run the Runnable again. It's just ... incomprehensible.

After commething out these lines:

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

The memory leaks seems like plugged. Why is setText() leaking memory? Question is kinda answered, but still why?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top