简体   繁体   中英

How do I prevent Memory leaks when using JTextPane?

I have a JFrame containing a button. When the button is clicked, it opens a window containing a JTextPane with a lot of text.

  1. At the begining, the application takes up 35 mb memory.
  2. When new window is opened, the application takes up ~200 mb worth of memory.
  3. When the new window is closed, the application takes up ~120 mb worth of memory.
package main;

import javax.swing.*;
import java.awt.*;

public class MemoryLeakTest {
    public void start(){
        JFrame frame = new JFrame();
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        JButton button = new JButton("Create new window");
        button.addActionListener(l->{
            createWindow();
        });
        frame.add(button);
        frame.setVisible(true);
    }
    public void createWindow(){
        window w = new window();
        w.setVisible(true);
    }
    public static void main(String[] args) {
        new MemoryLeakTest().start();
    }
}

class window extends JFrame {
    private JTextPane textPane;

    public window() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(500, 500);
        textPane = new JTextPane();
        textPane.setText(extremelyLongText());
        add(textPane);
        System.out.println("New window created!");
    }

    public String extremelyLongText() {
        StringBuilder builder = new StringBuilder();
        for (int j = 0; j < 1000; j++, builder.append("\n"))
            for (int i = 0; i < 10000; i++, builder.append("a")) ;
        return new String(builder);
    }

    @Override
    public void dispose() {
        super.dispose();
        textPane.setText("");
        System.gc();
        textPane= null;
        System.gc();
    }
}

I have overridden the dispose method to set this JTextPane to null. I expected the memory consumption to go back down to 35 mb, but it drops to only 120 mb. Why is this happening? Is the string in JTextPane not getting Garbage Collected? How do i ensure that memory is freed up whenever I use a JTextPane ?

Edit: I am using jdk 16 on Windows 10 to test this, and i am seeing the memory usage on task manager

Don't expect System.gc() to force a gc. Some jvm's don't even do anything when it is called. The jvm is allowed to do gc whenever it it decides to.

Well, it looks like there is no memory leak happening. Running the program under jconsole revealed that the heap memory does return to original size after closing the new windows:

在此处输入图像描述

However, the non heap memory increases significantly when the 1st window is created:

在此处输入图像描述

the non heap memory stays pretty much the same even after creating the 2nd window, or even a 3rd, so i guess there isn't much of a problem here.

I am not aware of any way to release non-heap memory, but i guess it is safe to say that the above code is correct, and there is no memory leak happening. (Although only the last System.gc() call is enough)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM