JDK-8241972 : SwingNode memory leak
  • Type: Bug
  • Component: javafx
  • Sub-Component: swing
  • Affected Version: openjfx11
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2020-03-31
  • Updated: 2021-03-01
  • Resolved: 2020-04-11
Related Reports
Duplicate :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
PC / Windows 10 Professional / Java 11.0.6

A DESCRIPTION OF THE PROBLEM :
Calling javafx.embed.swing.SwingNode#setContent will not dispose previously set content which can possibly produce massive memory leaks.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run provided SSCCE
2. Attach with VisualVM
3. Press "Set new Swing Node content" few times
4. The memory Heap size should increase
5. Press "Perform GC" in VisualVM



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Previously set content (which is not used anymore) should be properly disposed.
ACTUAL -
References to previously set content are still there. It looks like Swing disposer is to blame:

com.sun.javafx.embed.swing.Disposer --> ... --> BigTestComponent

---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

public class SwingFx extends Application {

	@Override
	public void start(Stage stage) {
		final SwingNode swingNode = new SwingNode();

		Button bt = new Button("Set new Swing Node content");
		bt.setOnMouseClicked(event -> createAndSetSwingNodeContent(swingNode));

		BorderPane borderPane = new BorderPane();
		borderPane.setTop(bt);
		borderPane.setCenter(swingNode);
		stage.setScene(new Scene(borderPane, 200, 150));
		stage.show();
	}

	private void createAndSetSwingNodeContent(SwingNode swingNode) {
		SwingUtilities.invokeLater(() -> {
			swingNode.setContent(null);
			swingNode.setContent(new BigTestComponent());
		});
	}

	public static void main(String[] args) {
		launch(args);
	}


	private static class BigTestComponent extends JComponent {
		private final Double[] bigArray;

		public BigTestComponent() {
			bigArray = new Double[20_000_000];
		}
	}

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Unfortunately I haven't found any workaround for this. It's actually a blocker for us. 


FREQUENCY : always



Comments
Seems to be a duplicate of JDK-8218124
11-04-2020