Bug 1312

Summary: GLContextShareSet memory leak when repeatedly creating and removing GLDrawables
Product: [JogAmp] Jogl Reporter: Tom Nuydens <tom.nuydens>
Component: openglAssignee: Sven Gothel <sgothel>
Status: IN_PROGRESS ---    
Severity: normal CC: gouessej, sgothel
Priority: P4    
Version: 2.4.0   
Hardware: All   
OS: all   
Type: DEFECT SCM Refs:
Workaround: ---

Description Tom Nuydens 2016-06-09 09:13:35 CEST
My use case is an application that has one "main" GLDrawable which is always visible, and one or more "secondary" GLDrawables that can be opened and closed any number of times (e.g. in a separate window). I want all these drawables to do GL context sharing.

As long as the main drawable exists, however, GLContextShareSet seems to keep strong references to all the secondary ones that I have ever created. Hence, even though they have been destroyed, the secondary ones cannot be GC'ed. I couldn't see a good reason for this, and was able to work around it by replacing the maps in GLContextShareSet with "weak key" maps.
Comment 1 Tom Nuydens 2016-06-13 11:36:40 CEST
I submitted my workaround in a pull request:
Comment 2 Julien Gouesse 2016-07-06 09:01:46 CEST

I agree with your main statement, GLContextShareSet shouldn't keep strong references on objects that could become useless, it shouldn't prevent their garbage collection. I just wonder if there is a more simple solution to fix this bug. I have looked at your pull request.
Comment 3 Sven Gothel 2018-01-16 07:14:25 CET
Hi Tom, 

1st of all I would like to see a specific unit test for this,
we should have some already available - maybe we can fine tune them.

The actual bug you are hinting would be (using our terminology):

"GLContextShareSet seems to keep strong references to all the shared ones 
that I have ever created. 
Hence, even though they have been destroyed, the shared ones cannot be GC'ed"

'GLContextShareSet.unregisterSharing(this)' never gets called?

Which points us to the logic in GLContextImpl.destroy() #498:


if( GLContextShareSet.contextDestroyed(this) &&
    !GLContextShareSet.hasCreatedSharedLeft(this) ) {


I will investigate this one now.

The 'hard lifecycle' with strong references is intended to enforce
a proper user lifecycle call hierarchy, e.g. calling 'destroy()'.

Let's see what we can do here ..