Manual sink architecture #114
diamondburned
started this conversation in
Discussions
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Problem
Currently, gotk4 commonly suffers from the following problem which would cause
massive memory leaks due to limitations of the Go garbage collector:
This is because all closures must be stored in a global registry to be
referenced back later, which would cause
wto also be globally referenced,meaning its finalizer is never called, causing a memory leak.
Current State
The current workaround involves creating a weak reference to
wand using thatin the closure:
This works for at least GTK widgets, because signals should not own a strong
reference to the object unless it is being called. Signals are strictly only
relevant when the object itself is still alive.
However, this workaround has a limitation: it doesn't work if
wis stored in astruct and that struct itself is referenced, as it commonly is. Consider the
following example:
This may work if
mis also created as a weak reference in Go's allocatorsystem, possibly by using a third-party library that handles weak references
like xeus2001/go-weak:
Proposed Solution
The proposed solution is to do what GTK itself does: use a floating reference by
default when new objects are constructed. This means that, unless the object is
immediately referenced by something else, it will be destroyed in the next
iteration of the main loop.
What this means is that the following code will not cause a memory leak:
This is because, assuming
wis not referenced by anything else, it will bedestroyed in the next iteration of the main loop, and the closure will be
destroyed with it.
This code will cause
wto sink:This is because
wis now referenced byparent, and will not be destroyeduntil
parentis destroyed.However, this also means that if
wis stored for longer than the lifetime ofparent, it will be destroyed in the next iteration of the main loop, causingthe program to crash:
In this case, the user must manually sink
wto prevent it from beingdestroyed:
However, by manually sinking
w, the user must also manually destroy it:This doesn't actually destroy
wimmediately, it simply removes the sunkenreference so that Go's garbage collector can destroy it when it is no longer
referenced.
When sunken, references to
wwithin closures will cause the same memory leakas before:
However, note that the user should rarely need to sink objects. The only
time this should be necessary is when the user is storing an object for longer
than the lifetime of the object that references it. Doing so is already very
complicated, and the user should be aware of the consequences of doing so.
Implementation
TBD.
Beta Was this translation helpful? Give feedback.
All reactions