When a Node is removed from the scene graph and garbage collected that had "cache" set to true, it leaks the cached texture. I am testing an app on PI and noticed after a few iterations within the app that I'm getting "black rectangles". The fundamental problem is that we don't have full lifecycle management on the Node, such that we get no notification when it's peer is destroyed.
The best solution is probably to have a "destroy" method on the peer (NGNode), and whenever the Node finds it is removed from the scene graph (even temporarily) we destroy the peer and throw it away, and recreate it once the node is reattached to the scene graph.
The only case we want to optimize is the case where you move the child within the same parent, and possibly when you move it directly to a new parent. As long as it doesn't transition through "null", then we can watch the parent. If it ever goes null, then we have to destroy our peer and the peers of all of our children. I'm not sure this is even sufficient, as a root node has no parent, but still needs its peers destroyed when the scene is removed from a stage, or a stage is hidden.
So it seems like what we want is a package private API in javafx.scene.Node such as "disposeOfPeer". This would be called by the parent property on Node if it transitions to null (was not null, and now is null), unless the node is the root node of the scene. "disposeOfPeer" would walk down the tree destroying the peers of all the children. The scene would invoke this method on the old root when it is removed, and would also invoke it whenever it finds itself to have been removed from the stage.
Then we have to go through and make sure everybody is getting a handle to the peer through the getter method so that it can be recreated on demand.
The best solution is probably to have a "destroy" method on the peer (NGNode), and whenever the Node finds it is removed from the scene graph (even temporarily) we destroy the peer and throw it away, and recreate it once the node is reattached to the scene graph.
The only case we want to optimize is the case where you move the child within the same parent, and possibly when you move it directly to a new parent. As long as it doesn't transition through "null", then we can watch the parent. If it ever goes null, then we have to destroy our peer and the peers of all of our children. I'm not sure this is even sufficient, as a root node has no parent, but still needs its peers destroyed when the scene is removed from a stage, or a stage is hidden.
So it seems like what we want is a package private API in javafx.scene.Node such as "disposeOfPeer". This would be called by the parent property on Node if it transitions to null (was not null, and now is null), unless the node is the root node of the scene. "disposeOfPeer" would walk down the tree destroying the peers of all the children. The scene would invoke this method on the old root when it is removed, and would also invoke it whenever it finds itself to have been removed from the stage.
Then we have to go through and make sure everybody is getting a handle to the peer through the getter method so that it can be recreated on demand.
- blocks
-
JDK-8123424 Moving a root node to be the child of a new root node results in error in Parent.validatePG
- Closed
- relates to
-
JDK-8090091 image data associated with cached nodes that are removed from a scene are not aggressively released
- Open
-
JDK-8100710 Need mechanism for PG nodes to know when they are no longer part of a scene graph
- Resolved
-
JDK-8101914 Centralized resource management should use an aging algorithm to prioritize proactive resource limiting
- Resolved