# Problem with finalizers

**URL:** <https://discourse.julialang.org/t/problem-with-finalizers/897>\
**Category:** General Usage\
**Created:** [December 12, 2016, 7:03pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897 "2016-12-12T19:03:51Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 7:03pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/1 "2016-12-12T19:03:51Z")

</div>

I’m currently having some trouble with a finalizer cleaning up an object that is needed by another finalizer.

I have two objects, both of which contain pointers to some C object, one of which is a “context object” for the other (contains some information needed to clean the other up).

The first object R has a type that looks like this:

```julia
type SingularPolyRing
   ptr::some_c_thing1
end

```

The second object p say, has a type that looks like this:

```julia
type spoly
   ptr::some_c_thing2
   parent::SingularPolyRing

   function spoly(R::SingularPolyRing, p::some_c_thing2)
      z = new(p, R)
      finalizer(z, _spoly_cleanup)
      return z
   end
end

```

(Here \_spoly\_cleanup(z) calls some C function to clean up.)

Both objects have finalizers, but when julia is shut down, the finalizer for the first object R is always called before that of the second, even though the second object p contains a reference to the first object R!

I tried writing the finalizer for the spoly p as follows:

```julia
   function spoly(R::SingularPolyRing, p::some_c_thing2)
      z = new(some_c_thing2, R)
      finalizer(z, x -> _spoly_clear_fn(x, R))
      return z
   end

```

The reasoning is that surely the lambda/closure hangs onto a copy of R, preventing it from being cleaned up first. But alas, R is still cleaned up first, before `_spoly_clear_fn` gets called. I’ve verified this by putting print statements in the relevant C functions.

Is there a canonical way of preventing Julia from cleaning up an object that is needed to clean up another object?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 12, 2016, 7:55pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/2 "2016-12-12T19:55:56Z")

</div>

Finalizers can be called at any time after the object is dead in any order.

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 8:10pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/3 "2016-12-12T20:10:05Z")

</div>

Sure. But surely the object isn’t dead if something still has a reference to it.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 12, 2016, 8:15pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/4 "2016-12-12T20:15:16Z")

</div>

> [@wbhart](#):
>
> But surely the object isn’t dead if something still has a reference to it.

Not if the one referencing it is another dead object.

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 8:29pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/5 "2016-12-12T20:29:54Z")

</div>

So the solution seems to be that I need to maintain another reference to R somewhere. Presumably p is cleaned up because the REPL or some internal symbol table no longer has a reference to it.

Is there somewhere I can put R so that it is cleaned up after all the other global symbols, e.g. in Base or something like that?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 12, 2016, 8:59pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/6 "2016-12-12T20:59:58Z")

</div>

> [@wbhart](#):
>
> Is there somewhere I can put R so that it is cleaned up after all the other global symbols

No. It’s unclear what exactly is the behavior your need but maintaining a refcount manually can be a solution if that’s what the C library want.

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 9:12pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/7 "2016-12-12T21:12:22Z")

</div>

On the C side, p is basically a tagged union. R is a context object that contains a lookup table of function pointers for all objects that are tagged unions like p. The “generic” delete function for p requires you to pass both p and R so that it can look up which delete function it is supposed to be calling to clean up p. It looks at the type tag for p to determine which function needs to be called.

Some libraries would just maintain a pointer to R inside p itself, but for extremely performance critical stuff, where memory usage is really important, p can’t hold a pointer to R and so you have to pass both p and R to delete. That means on the Julia side, the object R is needed to clean up p, which means you can’t clean up R first.

Anyway, I’ll see if I can find some information about maintaining refcounts. Perhaps a solution will suggest itself.

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 9:26pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/8 "2016-12-12T21:26:28Z")

</div>

Just Googling refcount Julia doesn’t seem to be turning up anything relevant. Is the idea that you can somehow assign a refcount to finalized objects? Where would I find this?

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 9:54pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/9 "2016-12-12T21:54:27Z")

</div>

It’s ok, I think I figured out what you mean. You meant to manually maintain a refcount to R from all objects p that depend on it. All the finalizer for R would do is decrease the refcount. And only when there are really zero references would the actual C delete function be called.

That should work ok, I think. I’ll give it a try.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 12, 2016, 10:15pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/10 "2016-12-12T22:15:12Z")

</div>

Correct. \<20 characters limit …\>

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 10:36pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/11 "2016-12-12T22:36:59Z")

</div>

This works fine. Thanks for the suggestion.

Just to document for others who find the thread, here is what I did:

- Inside the Julia type for R I added an additional field “refcount”, which is initially set to 1.
- The finaliser for R decrements the refcount field and if the refcount == 0 it calls the C delete function.
- The finaliser for p first cleans up p by calling the relevant C delete function, then it calls the finaliser for R directly (which as mentioned decrements the refcount by one more and checks if it is time to clean up R).

---

<div class="post-metadata">

**Author:** ![LewisHein](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lewishein/32/5690_2.png) [@LewisHein](https://discourse.julialang.org/u/LewisHein)\
**Post date:** [December 12, 2016, 10:54pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/12 "2016-12-12T22:54:03Z")

</div>

I don’t mean to horn in here, but I think this could cause a problem if you have more than one reference to an R running around. Say, like the following  
` x = R() y=x`

Is the reference count incremented at the y=x call? If not, couldn’t you end up with x being garbage-collected out from under you?

---

<div class="post-metadata">

**Author:** ![wbhart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wbhart/32/4714_2.png) [@wbhart](https://discourse.julialang.org/u/wbhart)\
**Post date:** [December 12, 2016, 11:00pm UTC](https://discourse.julialang.org/t/problem-with-finalizers/897/13 "2016-12-12T23:00:01Z")

</div>

I think that’s ok. The finalizer for R can’t get called by the gc itself unless there are no references to it. That’s why the refcount starts at 1 and not zero. That final refcount is for R itself. In your example, only when x and y both die is the finalizer for the actual object called by the gc.

I checked that this seems to not be a problem, anyway.

We actually have to keep a global dictionary of all R’s anyway (since we need the R’s to be singletons), so the only way the final reference to R can be zeroed is if the dictionary gets cleaned up, which can only happen in our case upon exit from Julia. Still, I don’t think this is a problem even without the dictionary.
