1

In the example below MainFrame creates other JFrames. These newly created frames have DISPOSE_ON_CLOSE set as default close operation. When I click the close button, frames disappear but still are available from Window.getWindows() method. When I open let's say 4 windows, close them and click "Print windows counts" it shows

Windows: 4

How to make them disappear permanently from all Swing resources that aren't controlled by me?

In the real world these frames hold many other references and it causes memory leaks as they are never subject to be garbage collected.

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Window;

public class MainFrame extends JFrame {

    public static void main(String[] args) {
        MainFrame t = new MainFrame();
        SwingUtilities.invokeLater(() -> t.setVisible(true));
    }

    public MainFrame() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JButton newWindowButton = new JButton("Open window");
        newWindowButton.addActionListener((action) -> {
            JFrame otherFrame = createChildFrame();
            otherFrame.setVisible(true);
        });

        JButton printWidnowsButton = new JButton("Print windows count");
        printWidnowsButton.addActionListener((action) -> {
            System.out.println("Windows: " + Window.getWindows().length);
        });

        Container cp = getContentPane();
        cp.setLayout(new BorderLayout());
        cp.add(newWindowButton);
        cp.add(printWidnowsButton, BorderLayout.SOUTH);

        pack();
    }

    private JFrame createChildFrame() {
        JFrame otherFrame = new JFrame();
        otherFrame.setBounds(0, 0, 100, 100);
        otherFrame.setDefaultCloseOperation(
            WindowConstants.DISPOSE_ON_CLOSE);
        return otherFrame;
    }
}
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59

2 Answers2

1

In the real world these frames hold many other references and it causes memory leaks as they are never subject to be garbage collected.

These windows are stored as weak references, so they can be removed from memory by garbage collector.

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • It seems to be the right answer. O opened JVisualVm and invoked garbage collection. After that window count is 1 (only main frame remained). Thanks. – Wojciech Wirzbicki Nov 06 '17 at 10:02
-1

Thought the java doc says "the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.", I've been told that it will happen when all the references of the JFrame and its childs are gone.

So if you do JFrame yourFrame = null; it should work.

tec
  • 999
  • 3
  • 18
  • 40
  • 1
    If you look at op's code you can see they don't keep a reference to the jframe they want to close. – matt Nov 06 '17 at 09:08
  • Matt is right, I don't keep any reference to JFrame. Swing does. The otherFrame is a local reference kept on stack's frame (lamba code). – Wojciech Wirzbicki Nov 06 '17 at 09:59
  • A reference (between variable name and memory position) is created just making use of reserved word `new`. So yes, you have a reference for each object created. Then, to release the memory from the JFrame object you can use reserved word `null`. Regards. – tec Nov 06 '17 at 10:17
  • 1
    @tomyforever It would only mark it eligible for garbage collection, assuming that the system didn't maintain a reference to any parts of it (i.e. the native resources or listeners). Even then, Swing tends to keep hold of a single single window – MadProgrammer Nov 06 '17 at 10:25
  • @MadProgrammer you are right, but my answer isn't wrong either. Why did I get negative vote? Many answers talk about asign `null` and garbage collector. https://stackoverflow.com/questions/5757552/deleting-an-object-in-java – tec Nov 06 '17 at 10:54
  • @tomyforever Because the references to the frame the OP have are local references, so as soon as they go out of scope, their code no longer maintains a reference to them, it's only the system which is maintaining the strong reference which is preventing them from been GC'd, so setting the reference to `null` is pointless. Also, I think, because of the way it reads, it suggests that as soon as you make a reference null, the object is freed, which isn't true - but I didn't downvote you – MadProgrammer Nov 06 '17 at 20:43