You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GL resources are non-heap objects that are allocated through the application's GL context and are somewhere in memory but are not destroyed via Java's garbage collection. Examples of such objects are FBO, Shader, and VertexArray.
Current state
Currently the classes that are responsible for the GL resource implement the AutoClosable so the compiler occasionally reminds the developer to close such an object, where close() takes care of destruction of the GL resources.
* Disposes of this {@link VertexArray} GL resources, i.e.
* deletes GL buffer and vertex array objects.
*/
@Override
@GLContextRequired
publicvoidclose() {
for(inti = 0; i < vbos.length; i++){
glDeleteBuffers(vbos[i]);
vbos[i] = 0;
}
glDeleteBuffers(ibo);
glDeleteVertexArrays(va);
ibo = va = 0;
}
However, the delete calls in close() only work when the GL context that created the resources is active, hence the @GLContextRequired annotation. In order for close() to work, it needs to be called during rendering of the FBOCanvas (or parent AWTGLCanvas) or using the canvas' runInContext(Runnable) method.
Since this is all a lot to remember there is a mechanic to automatically call close() on the various GL resource holding objects when the window that displays the FBOCanvas closes.
The close() call on FBOCanvas implies close() on subclass BlankCanvas which starts a close() cascade into its Renderer which in turn closes it's attached Renderable items (such as Linse or Points).
Problem
While this works for the specific case that all GL resources are somehow connected to the render tree of BlankCanvas, i.e., all created renderers are reachable from BlankCanvas (e.g. through ChainedRenderer or CompleteRenderer) and all of the created Renderables are also reachable from their Renderers.
If for example a Renderer was replaced through BlankCanvas.setRenderer(Renderer), it is no longer reachable and needs to be closed() manually. Same goes for Renderable objects that are removed through removeItemToRender(Renderable).
Such objects are floating around and garbage collected eventually if not used anymore, but without successful GL resource deletion due to missing the active GL context. This can potentially pollute graphics memory.
Possible solution
There are 2 parts to the solution
The object that hosts the GL context (FBOCanvas) keeps track of all the resources that are allocated. Classes that create GL resources need to report to the canvas in this case. When FBOCanvas closes, it deletes all the resources that it kept track of.
when GL resource holding objects are garbage collected (without the canvas being closed), they tell FBOCanvas to delete their resources later.
There is one caveat though: In order to implement 2. the object needs to know that it is now about to be garbage collected. Prior to Java 9 this would be done with Object.finalize(). However, finalize() has been deprecated since and replaced with the Cleaner mechanic. JPlotter is currently compatible with Java 8, and would need to be updated to a newer version of Java like 11 LTS.
Since the support for Java 8 has long been discontinued, there is no reason to keep compatibility. So the first step towards this issue is to migrate to Java 11.
The text was updated successfully, but these errors were encountered:
GL resources are non-heap objects that are allocated through the application's GL context and are somewhere in memory but are not destroyed via Java's garbage collection. Examples of such objects are
FBO
,Shader
, andVertexArray
.Current state
Currently the classes that are responsible for the GL resource implement the
AutoClosable
so the compiler occasionally reminds the developer to close such an object, whereclose()
takes care of destruction of the GL resources.JPlotter/jplotter/src/main/java/hageldave/jplotter/gl/VertexArray.java
Lines 210 to 224 in 82d78a8
However, the delete calls in
close()
only work when the GL context that created the resources is active, hence the@GLContextRequired
annotation. In order forclose()
to work, it needs to be called during rendering of theFBOCanvas
(or parentAWTGLCanvas
) or using the canvas'runInContext(Runnable)
method.Since this is all a lot to remember there is a mechanic to automatically call
close()
on the various GL resource holding objects when the window that displays theFBOCanvas
closes.JPlotter/jplotter/src/main/java/hageldave/jplotter/canvas/JPlotterCanvas.java
Lines 353 to 371 in 82d78a8
JPlotter/jplotter/src/main/java/hageldave/jplotter/canvas/FBOCanvas.java
Lines 748 to 755 in 82d78a8
The
close()
call onFBOCanvas
impliesclose()
on subclassBlankCanvas
which starts aclose()
cascade into itsRenderer
which in turn closes it's attachedRenderable
items (such asLinse
orPoints
).Problem
While this works for the specific case that all GL resources are somehow connected to the render tree of
BlankCanvas
, i.e., all created renderers are reachable fromBlankCanvas
(e.g. throughChainedRenderer
orCompleteRenderer
) and all of the createdRenderable
s are also reachable from theirRenderer
s.If for example a Renderer was replaced through
BlankCanvas.setRenderer(Renderer)
, it is no longer reachable and needs to be closed() manually. Same goes forRenderable
objects that are removed throughremoveItemToRender(Renderable)
.Such objects are floating around and garbage collected eventually if not used anymore, but without successful GL resource deletion due to missing the active GL context. This can potentially pollute graphics memory.
Possible solution
There are 2 parts to the solution
FBOCanvas
) keeps track of all the resources that are allocated. Classes that create GL resources need to report to the canvas in this case. WhenFBOCanvas
closes, it deletes all the resources that it kept track of.FBOCanvas
to delete their resources later.There is one caveat though: In order to implement 2. the object needs to know that it is now about to be garbage collected. Prior to Java 9 this would be done with
Object.finalize()
. However,finalize()
has been deprecated since and replaced with theCleaner
mechanic. JPlotter is currently compatible with Java 8, and would need to be updated to a newer version of Java like 11 LTS.Since the support for Java 8 has long been discontinued, there is no reason to keep compatibility. So the first step towards this issue is to migrate to Java 11.
The text was updated successfully, but these errors were encountered: