# Freeing memory withing struct

**URL:** <https://discourse.julialang.org/t/freeing-memory-withing-struct/23031>\
**Category:** General Usage\
**Tags:** memory-allocation\
**Created:** [April 11, 2019, 12:04pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031 "2019-04-11T12:04:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [April 11, 2019, 12:04pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/1 "2019-04-11T12:04:35Z")

</div>

```julia
julia> mutable struct S
           x::Vector{Matrix{Float64}}
           S() = new()
       end

julia> s = S();

julia> s
S(#undef)

julia> s.x
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getproperty(::Any, ::Symbol) at .\sysimg.jl:18

julia> s.x = [rand(1000,1000) for i in 1:100]; # takes up memory

```

Initially the field `x` is undefined (taking up basically no memory). After the assignment, some piece of memory is assigned to `s.x`. Is there a nice way to free up this memory again, that is, for example, get `s.x` back to be `#undef`?

Outside of a struct, the typical answer seems to be set `x = nothing` and perhaps call `GC.gc()` to free the memory. But this doesn’t work for a field of a struct as the memory could still be accessed (it’s still reachable).

I can set `s.x = Matrix{Float64}[]` and call `GC.gc()` to free the memory. I’m just wondering if there is a better approach.

To give you some context, I have a couple of costly operations that I perform in-place in some preallocated memory. To that end I have a struct, say `Preallocations`, whose fields are being used as preallocated memory. However, the memory assigned to some of those fields might be very large and only needed in some operations. After those operations finish I’d like to free the memory again.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [April 11, 2019, 12:27pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/2 "2019-04-11T12:27:37Z")

</div>

> [@carstenbauer](#):
>
> get `s.x` back to be `#undef` ?

That is not possible.

For your example, why not just de-reference the `Preallocations` instance? Say by letting it go out of scope?

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [April 11, 2019, 12:51pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/3 "2019-04-11T12:51:51Z")

</div>

You can use `::Union{Nothing, Vector{Matrix{Float64}}}`. IIUC its cost will be ~1 byte, and the performance impact should be negligible for most use cases.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 11, 2019, 12:55pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/4 "2019-04-11T12:55:02Z")

</div>

`sizehint!(s.x, 0)` works even with non mutable structs.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [April 11, 2019, 1:18pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/5 "2019-04-11T13:18:14Z")

</div>

A different variant is `s.x=Vector{Matrix{Float64}}[]`. If you store many `S` instances and don’t want to pay the `jl_array` memory price, it might be advisable to have some `const _nil = Vector{Matrix{Float64}}[]` and set `s.x = _nil`.

Then you can also initialize with `_nil`, and check for initialized-ness by `s.x === _nil` (triple `===`, about as fast as `issassigned(s, :x)` and much faster than `==` because you avoid dereferencing the pointer).

By making the field `s.x` always assigned (by not having an inner constructor) you speed up every single access (if the inner constructor permits unassigned `s.x` then julia emits nullpointer checks on access).

Downside: If your code is buggy, then someone can forget the `s.x === _nil` check and actually mutate the global `_nil`. Nobody will protect you from this bug, because you intentionally removed all guardrails.

If you care more about maintainability than raw speed, then `Union{Nothing, Vector{Matrix{Float64}}}` is probably more appropriate.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [April 11, 2019, 1:30pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/6 "2019-04-11T13:30:19Z")

</div>

> [@mauro3](#):
>
> For your example, why not just de-reference the `Preallocations` instance? Say by letting it go out of scope?

`Preallocations` would also hold preallocations for other operations so de-referencing the instance doesn’t work.

> [@cstjean](#):
>
> You can use `::Union{Nothing, Vector{Matrix{Float64}}}`. IIUC its cost will be ~1 byte, and the performance impact should be negligible for most use cases.

Thanks, but I’d like to avoid unions here, mainly for readability reasons.

> [@kristoffer.carlsson](#):
>
> `sizehint!(s.x, 0)` works even with non mutable structs.

`sizehint!` doesn’t seem to give the desired effect. However, `resize!(s.x, 0)` does. Thanks.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [April 11, 2019, 1:35pm UTC](https://discourse.julialang.org/t/freeing-memory-withing-struct/23031/7 "2019-04-11T13:35:16Z")

</div>

> `Preallocations` would also hold preallocations for other operations

Use separate ones?

I think Kristoffer means you should use:

```julia
empty!(s.x)
sizehint!(s.x, 0)

```

as otherwise the “reserve” size for `s.x` stays at the large size and occupies memory (I think).
