# Calling Finalize from Running Finalizer

**URL:** <https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365>\
**Category:** General Usage\
**Created:** [June 8, 2024, 3:57pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365 "2024-06-08T15:57:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)\
**Post date:** [June 8, 2024, 3:57pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365/1 "2024-06-08T15:57:45Z")

</div>

I haven’t found it in the documentation, so I wanted to have it confirmed/documented:

Assume you have two objects, both having a finalizer. One finalizer needs to be called before the other, because there is a dependency. Then you can’t simply call `finalize` of the other object in the `finalizer`. Is this correct?

This can probably best explained with an example:

```julia
cprintln(str) = ccall(:jl_safe_printf, Cvoid, (Cstring, ), str * "\n")

mutable struct A
    A() = finalizer(new()) do a
        cprintln("In finalizer A")
    end
end

mutable struct B
    B(a) = finalizer(new()) do b
        cprintln("Begin finalizer B")
        finalize(a)
        cprintln("End finalizer B")
    end
end

b = B(A())
b = nothing
Base.GC.gc()

```

results in

> Begin finalizer B  
> End finalizer B  
> In finalizer A

So I assume the [documentation for `finalize`](https://docs.julialang.org/en/v1/base/base/#Base.finalize) is incorrect, because instead of

> Immediately run finalizers registered for object `x`.

it should be probably something like (just guessing, please enter the correct wording):

> Registers to run finalizers registered for object `x` as soon as possible (often immediately, but sometimes delayed for example while already running in another finalizer)

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 8, 2024, 4:38pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365/2 "2024-06-08T16:38:49Z")

</div>

Several thoughts:

1. You might not want to rely on GC to finalize.
2. To delay finalization, you can reinstall the finalizer in finalize.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [June 8, 2024, 6:22pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365/3 "2024-06-08T18:22:30Z")

</div>

If I remember correctly when we locate a group of unreachable objects we “detach” the finalizers and copy them into a separate list. Then we run all the finalizers in that list.

So when you call `finalize(a)` inside the finalizer there is no finalizer attached anymore and thus none to execute.

---

<div class="post-metadata">

**Author:** ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)\
**Post date:** [June 14, 2024, 3:01pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365/4 "2024-06-14T15:01:57Z")

</div>

Thanks, that explains the behavior. What wording do you recommend for the documentation to reflect that?

---

<div class="post-metadata">

**Author:** ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)\
**Post date:** [June 14, 2024, 3:42pm UTC](https://discourse.julialang.org/t/calling-finalize-from-running-finalizer/115365/5 "2024-06-14T15:42:01Z")

</div>

Thanks, I introduced a do-block syntax so that the finalizers only act as a (probably unnecessary) safeguard. Maybe I’ll get rid of them in the future, because they seem to be not without problems.

Meanwhile I registered both finalizers for the same object. Finalizers of different objects race (calling order is non-deterministic), while having multiple finalizers for the same object leads to deterministic behavior: The finalizer defined last will be called first which is what you normally want when freeing resources.

Coming from statically typed languages having an object of type B registering as a finalizer on an object of type A seems to be counter-intuitive, but works quite well (for a finalizer). This probably only makes sense if the lifetime of the objects is really coupled, which is the case in my real problem.

This would be the example to ensure that finalizer A is always running before finalizer B:

```julia
cprintln(str) = ccall(:jl_safe_printf, Cvoid, (Cstring, ), str * "\n")

mutable struct A; end
addfinalizer(a::A) = finalizer(a) do a
    cprintln("In finalizer A")
end

mutable struct B; end
addfinalizer(b::B, a::A) = finalizer(a) do b
    cprintln("In finalizer B")
end

a = A()
b = B()
addfinalizer(b, a)
addfinalizer(a)

a = b = nothing
Base.GC.gc()

```
