This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-08
Channels
- # announcements (1)
- # babashka (18)
- # beginners (32)
- # calva (3)
- # chlorine-clover (4)
- # cider (14)
- # clj-commons (24)
- # clj-kondo (1)
- # clojure (34)
- # clojure-europe (4)
- # clojure-filipino (1)
- # clojure-uk (4)
- # clojuredesign-podcast (2)
- # clojurescript (6)
- # conjure (3)
- # core-async (2)
- # datahike (1)
- # datomic (3)
- # emacs (3)
- # esprit (20)
- # fulcro (4)
- # graalvm (11)
- # helix (13)
- # honeysql (4)
- # jobs (1)
- # lumo (1)
- # observability (4)
- # off-topic (11)
- # other-lisps (6)
- # pathom (6)
- # re-frame (13)
- # reagent (1)
- # reitit (1)
- # shadow-cljs (26)
- # web-security (2)
- # xtdb (10)
does anyone have any examples or guidance on hooking up a deftype
to the GC? I want to detect when my object is collected so I can do some cleanup
I see that finalizers were deprecated in Java 9, which is unfortunate because it's about as much control as I want
in this case it's very much part of the domain I'm working in. I'm working on a general lib for creating reactive graph of objects; so I have references from node to node and back again. keeping references around after they can't be accessed anymore is no fun
I've already done the work of implementing simple reference counting so I can dispose of whole trees once they're explicitly cut off from the graph, the only issue is if a user loses access to a node then I don't have a way of detecting that it's been GC'd
the user can manually call a dispose
function on it, which would probably be best practice, so my goal is just to do a best-effort attempt at cleaning up the graph when I detect a node has been GC'd
maybe your problem domain is loosely analog to Clojure's persistent data structures? Probably there are some interesting interactions between structural sharing and GC
IIRC Clojure's persistent data structures (and most data structures I would guess) only reference parent -> child
this is nice(ish) for GC because once a parent is no longer referenced, then it can be GC'd, which will remove reference to the child, and so on
in the case of my reactive graph, each node tracks not only other nodes it references, but also other nodes that reference it (a backwards reference). this way, when it's updated, it can tell nodes that are subscribed to it that it has been updated so they can recalculate their values.
this is bad for GC, because it means that even if a parent node is orphaned, it can't be cleaned up because of this circular reference
the way I'm handling it now is I have a special kind of node that can only contain forward references. So it can be GC'd. what I'd like to do is detect when those nodes are GC'd
@U4YGF4NGM i think weak references will do what you want, https://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html
yea. theres also a handful of other tools in that space, but they’re all kind of tricky. i think weakreference is the most straight forward. https://docs.oracle.com/javase/8/docs/api/java/lang/ref/package-summary.html#reachability has even more options
that seems pretty heavy weight for my case, since I'm already doing the work of reference counting internally so that I can stop propagating changes to nodes that aren't referenced any more
it would be much simpler (and probably more performant?) if I could tell when my output nodes have been GCd and call my own disposal method, rather than rely on GC to clean up all of my graph
makes sense. not sure what type of cleanup you need to do. the docs in java 9 for finalize point to cleaner and phantom reference which both seem interesting: • https://docs.oracle.com/javase/9/docs/api/java/lang/ref/Cleaner.html • https://docs.oracle.com/javase/9/docs/api/java/lang/ref/PhantomReference.html
the way I'm handling it now is I have a special kind of node that can only contain forward references. So it can be GC'd. what I'd like to do is detect when those nodes are GC'd
In a Clojure var, there is a boolean threadBound
which is set to true
in push-thread-bindings
. When and where does that boolean return to the false
state?
pop-thread-bindings?
Not looking at code, just guessing :)
I would guess so too, but I can't find it: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Var.java#L333-L342
I think there is actually a jira about this
to count the amount of thread-bindings that have been pushed and popped, and when it's back to zero, it's not threadBound anymore?
it seems that right now you're paying a small penalty for dynamic vars that have been bound once