tambre
tambre

Reputation: 4863

JFrame leaking memory?

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

Upvotes: 1

Views: 256

Answers (3)

Russell Zahniser
Russell Zahniser

Reputation: 16364

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)

Upvotes: 2

Stephen C
Stephen C

Reputation: 719739

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.

Upvotes: 2

tambre
tambre

Reputation: 4863

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?

Upvotes: 1

Related Questions