# Don't understand why code runs out of memory and crashes

**URL:** <https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559>\
**Category:** General Usage\
**Tags:** memory, crash\
**Created:** [December 7, 2024, 8:24am UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559 "2024-12-07T08:24:26Z")\
**Posts on this page:** 10\
**Page:** 2

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [December 7, 2024, 3:31pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/22 "2024-12-07T15:31:39Z")

</div>

> [@Davide98888](#):
>
> Even then, I just dont know how to preallocate in multithreading code like this. Would need to pre-allocate one vector per core, and be able to use that correctly. Maybe possible, I just don’t know how, I’ll take a closer look at the docs.

There is a function `task_local_storage()` which gives you an `IdDict` which is local to your task. It can be used to store a vector under some name, e.g. with

```julia
v = get!(() -> Vector{Float64}(), task_local_storage(), :myvec)::Vector{Float64}
resize!(v, N)

```

Here’s a macro which automates away the uglyness, and creates a unique name for the vector:

```julia
macro tlscache(type)
    sym = Expr(:quote, gensym("tls"))
    quote
        get!(() -> $(esc(type))(), Base.task_local_storage(), ($sym,$(esc(type))))::$(esc(type))
    end
end

```

Use as:

```julia
x = @tlscache Vector{Float64}
resize!(x, N)
randn!(x)
sort!(x)

```

By using `resize!`, the vector is only reallocated if the size `N` is larger then before. If `N` is always the same, you allocate only the first time, and you get one vector per task.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 7, 2024, 4:22pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/23 "2024-12-07T16:22:12Z")

</div>

> [@Salmon](#):
>
> note I also replaced `Int(1e7)` by rounding.

Should really use `10^7` instead of messing with floats.

---

<div class="post-metadata">

**Author:** ![d-netto](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/d-netto/32/212022_2.png) [@d-netto](https://discourse.julialang.org/u/d-netto)\
**Post date:** [December 7, 2024, 4:48pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/24 "2024-12-07T16:48:01Z")

</div>

Ran this reproducer and the reproducer from [Memory leak with Julia 1.11's GC (discovered in SymbolicRegression.jl) · Issue #56759 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/56759) with `GC.enable_logging`. Seems like in both of them, heap size increases, but most of it is mallocd memory (not pool allocated memory), which doesn’t shrink even if you run a GC.

Didn’t investigate further yet to know whether it’s related, but seems suspicious…

See [Memory leak with Julia 1.11's GC (discovered in SymbolicRegression.jl) · Issue #56759 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/56759#issuecomment-2525241462)

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 7, 2024, 5:04pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/25 "2024-12-07T17:04:42Z")

</div>

> [@d-netto](#):
>
> Seems like in both of them, heap size increases, but most of it is mallocd memory (not pool allocated memory), which doesn’t shrink even if you run a GC.

That does seem to be it - I can also see in `top` that it’s the resident memory that increases. Whether this is a true “memory leak” in the sense that the memory is inaccessible to the GC is debatable (presumable it could be freed & is technically reachable by the GC?), but the point that this increase is unexpected holds.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [December 7, 2024, 5:48pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/26 "2024-12-07T17:48:49Z")

</div>

Not a solution to the GC / memory leak issue, but OhMyThreads.jl has a lot of nice functionality for efficient allocations in multithreaded code.

---

<div class="post-metadata">

**Author:** ![Davide98888](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Davide98888](https://discourse.julialang.org/u/Davide98888)\
**Post date:** [December 7, 2024, 6:17pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/27 "2024-12-07T18:17:53Z")

</div>

Wow, thanks @gdalle , I had not seen that, already put to good use. There are so many fantastic Julia packages, (that I sadly miss)

d

---

<div class="post-metadata">

**Author:** ![Fliks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fliks/32/2494_2.png) [@Fliks](https://discourse.julialang.org/u/Fliks)\
**Post date:** [December 9, 2024, 3:05pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/28 "2024-12-09T15:05:42Z")

</div>

I am wondering whether this might be related to this Julia issue:

> <https://github.com/JuliaLang/julia/issues/40626>
>
> When returning values from tasks executed on another thread, those values are ke…pt alive even though it should be possible to collect them:
> 
> \`\`\`julia
> julia\> a = \[2,2\];
> julia\> finalizer(a) do \_
> Core.println("finalizing a")
> end
> 
> julia\> t = Threads.@spawn (println("returning a from thread $(Threads.threadid())"); a)
> Task (runnable) @0x00007fffb73e8e80
> returning a from thread 2
> 
> julia\> dump(t)
> Task
> next: Nothing nothing
> queue: Nothing nothing
> storage: Nothing nothing
> donenotify: Base.GenericCondition{Base.Threads.SpinLock}
> waitq: Base.InvasiveLinkedList{Task}
> head: Nothing nothing
> tail: Nothing nothing
> lock: Base.Threads.SpinLock
> owned: Int64 0
> result: Array{Int64}((2,)) \[2, 2\] # \<----------------- the array a is being kept alive by the task
> logstate: Nothing nothing
> code: #3 (function of type var"#3#4")
> \_state: UInt8 0x01
> sticky: Bool false
> \_isexception: Bool false
> 
> julia\> wait(t)
> julia\> a = nothing
> julia\> t = nothing
> julia\> GC.gc(true)
> 
> \# nothing is collected
> \`\`\`
> 
> Running under \`gdb\` reveals that the task object is being kept alive in the thread's local storage:
> 
> \`\`\`
> $ gdb --args julia -t2
> (gdb) run
> 
> julia\> code from above
> 
> (gdb) call jl\_(jl\_all\_tls\_states\[1\].current\_task)
> Task(next=nothing, queue=nothing, storage=nothing,
> donenotify=Base.GenericCondition{Base.Threads.SpinLock}(waitq=Base.InvasiveLinkedList{Task}(head=nothing, tail=nothing), lock=Base.Threads.SpinLock(owned=0)),
> result=Array{Int64, (2,)}\[2, 2\], # \<------------------- our array again
> logstate=nothing, code=Main.var"#3", \_state=0x01, sticky=false, \_isexception=false)
> \`\`\`
> 
> Running another task on the same thread replaces that sate and allows collection of the array:
> 
> \`\`\`julia
> julia\> # code from above
> 
> julia\> t = Threads.@spawn println("doing nothing from thread $(Threads.threadid())")
> Task (runnable) @0x00007fffb5b99e40
> doing nothing from thread 2
> 
> julia\> GC.gc(true)
> finalizing a
> \`\`\`
> 
> As observed in https://github.com/JuliaGPU/CUDA.jl/issues/866.

but I can’t reproduce the OOM with your example. According to the issue thread return nothing from the threaded loop might help in reducing the memory problems.

---

<div class="post-metadata">

**Author:** ![Davide98888](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Davide98888](https://discourse.julialang.org/u/Davide98888)\
**Post date:** [December 27, 2024, 5:01pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/29 "2024-12-27T17:01:43Z")

</div>

Hello

Thanks for all the replies. We eventually solved this, imperfectly, by writing a shell script that loops over the parameters and calls julia which runs simulation for one parameter set and exits. It works, but is far from elegant. There seems to be no alternative (I can make it take longer to run out of memory, but eventually it will). We asked around and few researchers told us this was the reason they did not use Julia for simulations.

We now have to put our code on a public githup page. It will not be nice to have the shell script work around for the memory leak, and I am contemplating re-writing the code in Python or R which don’t have this memory leak problem, and are about equally fast for this code.

But before I do that, wanted to ask a last time if this memory leak problem was about to be addressed, so we can wait, or if it is here to stay, in which case we have to use Python or R.

all the best, d

---

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [December 27, 2024, 8:56pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/30 "2024-12-27T20:56:36Z")

</div>

It seems that the memory leak were resolved thanks to reproducer you made [Memory leak with Julia 1.11's GC (discovered in SymbolicRegression.jl) · Issue #56759 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/56759#issuecomment-2532163107)  
I consider it to be success on how quickly such a nasty bug was found and resolved. You may be able to try it out by installing Julia nightly now with `juliaup` or with the next patch releases when it will be available.

---

<div class="post-metadata">

**Author:** ![Davide98888](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Davide98888](https://discourse.julialang.org/u/Davide98888)\
**Post date:** [December 27, 2024, 9:42pm UTC](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559/31 "2024-12-27T21:42:15Z")

</div>

Thanks @Janis_Erdmanis

Excellent news. I did not know this was being addressed, and so quickly.

I’ll be sure to give the nightly a spin, and delay putting our code on githup until the next release is out.

Our every interaction with Julia and its community validates using it. Both are truly fantastic.

best, d

[Previous page](https://discourse.julialang.org/t/dont-understand-why-code-runs-out-of-memory-and-crashes/123559.md?page=1)
