# Reference counting and disposables

**URL:** https://discourse.julialang.org/t/reference-counting-and-disposables/98875
**Category:** General Usage
**Tags:** design, garbage-collection
**Created:** [May 15, 2023, 11:43am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875 "2023-05-15T11:43:12Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [May 15, 2023, 11:43am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875/1 "2023-05-15T11:43:12Z")

</div>

In [ResourcePools.jl/pooled\_abstract\_array.jl at feature/multi-threading · IHPSystems/ResourcePools.jl · GitHub](https://github.com/IHPSystems/ResourcePools.jl/blob/feature/multi-threading/src/pooled_abstract_array.jl#L23), I have two concepts - in addition to pooled resources / pools of resources:

- Reference counted instances - that can be `retain!`'ed and `release!`'ed - and where something should happen when the reference count reaches zero. Thread-safe.
- Disposables - instances that react to `dispose!`, e.g., by cleaning up memory allocated outside Julia.

I have yet to find these quite common concepts in Base. Are they there somewhere or should they be split out into separate tiny packages?

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [August 12, 2023, 6:49am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875/2 "2023-08-12T06:49:27Z")

</div>

Another hit for looking up .NET-like disposables (IDisposable): [Iterators and resource management · Issue #22466 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/22466)

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [August 12, 2023, 8:21am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875/3 "2023-08-12T08:21:38Z")

</div>

Related to Disposables: [LLVM.jl defines a `@dispose` macro](https://github.com/maleadt/LLVM.jl/blob/v6.1.0/src/base.jl#L80) “for disposing resources without do-block syntax”:

> Helper macro for disposing resources (by calling the `LLVM.dispose` function for every  
> resource in reverse order) after executing a block of code. This is often equivalent to  
> calling the recourse constructor with do-block syntax, but without using (potentially  
> costly) closures.

Introduced in [Introduce at-dispose to replace do-block constructors. by maleadt · Pull Request #309 · maleadt/LLVM.jl · GitHub](https://github.com/maleadt/LLVM.jl/pull/309)

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [August 12, 2023, 8:37am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875/4 "2023-08-12T08:37:19Z")

</div>

See also this (concurrent) discussion: [https://julialang.zulipchat.com/#narrow/stream/137791-general/topic/Customizable.20or.20static.20memory.20allocation/near/383702361](https://julialang.zulipchat.com/#narrow/stream/137791-general/topic/Customizable.20or.20static.20memory.20allocation/near/383702361)

---

<div class="post-metadata">

### Author: ![stemann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stemann/32/4030_2.png) [@stemann](https://discourse.julialang.org/u/stemann)
#### Post date: [August 12, 2023, 8:56am UTC](https://discourse.julialang.org/t/reference-counting-and-disposables/98875/5 "2023-08-12T08:56:09Z")

</div>

@maleadt Care to comment on the prospect of “Disposables”? E.g. something outside LLVM that would do sort of the same thing…

I had something like the following (slightly bad idea) on my mind until looking at LLVM:

```julia
module Disposables

export dispose!, with_disposal

function dispose! end # dispose!(::T)

function with_disposal(f::Function, args...; kwargs...)
    try
        f(args...; kwargs...)    
    finally
        for arg in args
            dispose!(arg)
        end
    end
end

# test suite in a non-exported Testing sub-module for checking implementations of informal interface

# implementations of dispose!(::T) for Base types like arrays etc. ... - in a package extension or in a separate "DisposableBase" package

end # module

```

Issues:

- `dispose!` needs to consider interaction with GC - the same resource should not be disposed of twice in case someone hooks up `dispose!` to GC finalization with `finalizer` - similar to [how IDisposable works in .NET](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose) (cf. `IDisposable.Dispose(true)` vs `IDisposable.Dispose(false)`)
- `dispose!` must be implemented in a thread-safe manner - without risking dead locks. E.g. in relation to thread-safe reference counting (with both “disposable” and “reference countable” having a lock…)
- `with_disposal` seems problematic: Should all `arg in args` be disposed of? (probably not) Should they be disposed of in-order?

Something like the `@dispose` macro is probably better than `with_disposal`…
