RFR: 8263402: MemoryLeak: Node hardreferences it's previous Parent after csslayout and getting removed from the scene
Ambarish Rapte
arapte at openjdk.java.net
Fri Mar 12 07:59:09 UTC 2021
On Wed, 10 Mar 2021 22:25:32 GMT, Florian Kirmaier <fkirmaier at openjdk.org> wrote:
> Fixing a memory leak.
> A node hard references its old parent after CSS layout and getting removed.
> This shouldn't be the case, this is very counterintuitive.
>
> The fix uses a WeakReference in CSSStyleHelper for firstStyleableAncestor.
> This should be fine because the CSS should only depend on it if it's still the real parent.
> In that case, it doesn't get collected.
tests/system/src/test/java/test/javafx/scene/StyleMemoryLeakTest.java line 106:
> 104: });
> 105: }
> 106: }
In order to make this test similar to existing system tests, I made some relevant changes. Modified test is added below.
The modified test fails with this fix, but I expected it to pass. Can you please check this.
Changes are
1. `Thread.sleep()` is removed.
2. `root` and `toBeRemoved` button are now class members.
3. Scenegraph is constructed and shown in `TestApp.start()` method.
public class StyleMemoryLeakTest {
static CountDownLatch startupLatch;
static Stage stage;
static Button toBeRemoved;
static Group root;
public static class TestApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
stage = primaryStage;
toBeRemoved = new Button();
root = new Group();
root.getChildren().add(toBeRemoved);
stage.setScene(new Scene(root));
stage.setOnShown(l -> {
Platform.runLater(() -> startupLatch.countDown());
});
stage.show();
}
}
@BeforeClass
public static void initFX() throws Exception {
startupLatch = new CountDownLatch(1);
new Thread(() -> Application.launch(StyleMemoryLeakTest.TestApp.class, (String[])null)).start();
assertTrue("Timeout waiting for FX runtime to start", startupLatch.await(15, TimeUnit.SECONDS));
}
@Test
public void testRootNodeMemoryLeak() throws Exception {
Util.runAndWait(() -> {
root.getChildren().clear();
stage.hide();
});
JMemoryBuddy.memoryTest((checker) -> {
checker.assertCollectable(stage);
checker.setAsReferenced(toBeRemoved);
stage = null;
});
}
@AfterClass
public static void teardownOnce() {
Platform.runLater(() -> {
Platform.exit();
});
}
}
-------------
PR: https://git.openjdk.java.net/jfx/pull/424
More information about the openjfx-dev
mailing list