# Accumulating memory in nested loops

**URL:** <https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220>\
**Category:** General Usage\
**Tags:** performance\
**Created:** [April 14, 2017, 4:56pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220 "2017-04-14T16:56:01Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![WenlongGong](https://avatars.discourse-cdn.com/v4/letter/w/3d9bf3/32.png) [@WenlongGong](https://discourse.julialang.org/u/WenlongGong)\
**Post date:** [April 14, 2017, 4:56pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/1 "2017-04-14T16:56:02Z")

</div>

Is it normal that memory usage accumulate when running loops (many iterations including nested loops) inside a function in julia? I’m using Julia-0.4.5. and I think there is garbage collection in julia that helps clean memory.

I wrote a toy example of my code structure for the problem I encountered when running large scale simulation.

```julia
include("fcts.jl")
function sim(seed)
  #dummy=0
  A=[12,5,6,8,15,9];
  B=[4,12,19,5];
  C=[10,3,9,17];
  for iA=1:length(A), iB=1:length(B),iC=1:length(C)
    a=A[iA]*10^2; b=B[iB]*10^2; c=C[iC]*10^2
    srand(seed)
    M=randn(a,b)
   # tic(); Method1(); T11=toq()
   # tic(); Method2(); T12=toq()
   # tic(); Method3(); T13=toq()
    N=randn(a,c)
  ## measure corresponding time
    K=randn(b,c)
  ## measure corresponding time
  ## save results for each iteration in case the simulation stops b/c of error
  # filePath = "..."
  # fp = open(filePath*string(myid())*".csv", "a")
  # writecsv(fp,hcat(T11,T12,T13,...,seed))
  # close(fp)
  end
end

```

My original simulation runs with parallel `pamp(sim,1:30)`. But as monitoring the memory usage with “top” command in terminal, I find the memory accumulate gradually and finally the job get killed when it goes beyond the limit.

Could anyone tell me if there is any obvious problem which causes the heavy memory usage?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [April 14, 2017, 6:48pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/2 "2017-04-14T18:48:45Z")

</div>

Please quote (using `) and indent your code so that it is readable.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 14, 2017, 6:52pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/3 "2017-04-14T18:52:44Z")

</div>

(I edited your post to fix the code quoting.)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 14, 2017, 7:00pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/4 "2017-04-14T19:00:32Z")

</div>

> [@WenlongGong](#):
>
> Could anyone tell me if there is any obvious problem which causes the heavy memory usage?

You are allocating new `M`, `N`, and `K` matrices in each loop iteration. The old ones will eventually get garbage collected, but the memory usage reported by `top` is notoriously deceptive in garbage-collected languages. Top reports multiple numbers; are you looking at the RSS size?

---

<div class="post-metadata">

**Author:** ![WenlongGong](https://avatars.discourse-cdn.com/v4/letter/w/3d9bf3/32.png) [@WenlongGong](https://discourse.julialang.org/u/WenlongGong)\
**Post date:** [April 14, 2017, 7:26pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/6 "2017-04-14T19:26:00Z")

</div>

I read both VIRT and RES usage on top report gradually accumulate. IT support told me that RES " resident memory" is more relevant.  
Since the iterations are independent of each other, I thought the memory will be released after each iteration. Does it suppose to allocate new space each iteration? or There could be someway to get around?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 15, 2017, 2:24am UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/7 "2017-04-15T02:24:25Z")

</div>

> [@WenlongGong](#):
>
> I thought the memory will be released after each iteration.

Memory will be released eventually, but not immediately after each iteration. But it should be released long before memory starts to fill up. (See [Tracing garbage collection - Wikipedia](https://en.wikipedia.org/wiki/Tracing_garbage_collection))

I tried your code on my machine and didn’t see any problem. `map(sim, 1:30)` runs in about 100sec, and the memory usage fluctuates around 200MB the whole time. Can you give an minimal working example that actually demonstrates your problem?

---

<div class="post-metadata">

**Author:** ![WenlongGong](https://avatars.discourse-cdn.com/v4/letter/w/3d9bf3/32.png) [@WenlongGong](https://discourse.julialang.org/u/WenlongGong)\
**Post date:** [April 16, 2017, 12:35am UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/8 "2017-04-16T00:35:45Z")

</div>

Thanks for the reply!  
I made an example of my simulation which captures most of its feature. For simplicity, I’ve removed many steps including calling compiled C code. It can be downloaded here: [https://github.com/wenlongG/Example.git](https://github.com/wenlongG/Example.git)  
At the same time, I’m also checking the C code about proper memory release.

I’m not an expert in writing Julia functions, if there is some improper usage, please let me know. Thank you!

---

<div class="post-metadata">

**Author:** ![WenlongGong](https://avatars.discourse-cdn.com/v4/letter/w/3d9bf3/32.png) [@WenlongGong](https://discourse.julialang.org/u/WenlongGong)\
**Post date:** [April 16, 2017, 4:45pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/9 "2017-04-16T16:45:30Z")

</div>

I called C code many times in the original simulation study which return big sparse matrices to Julia for each iteration. I just realized that if I free the space in C then no value get passed to Julia.  
That could be the problem causing accumulating memory…But I don’t have better ways to deal with this.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 16, 2017, 8:47pm UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/10 "2017-04-16T20:47:03Z")

</div>

> [@WenlongGong](#):
>
> I called C code many times in the original simulation study which return big sparse matrices to Julia for each iteration. I just realized that if I free the space in C then no value get passed to Julia.

You have to make sure that Julia de-allocates this memory.

One option is to use the `own=true` keyword option to the [unsafe\_wrap](https://docs.julialang.org/en/stable/stdlib/strings/?highlight=unsafe_wrap#Base.unsafe_wrap) function, to convert a C-allocated pointer to a Julia array where Julia calls `free` on the memory when it is done.

Another option is to allocate the array in Julia and pass the pointer to C, letting the C code fill in the data as needed.

(If you are allocating lots of matrices in a loop and then discarding them, it is usually preferable from a performance perspective anyway to allocate the memory once, and then mutate the contents in the loop rather than re-allocating.)

---

<div class="post-metadata">

**Author:** ![WenlongGong](https://avatars.discourse-cdn.com/v4/letter/w/3d9bf3/32.png) [@WenlongGong](https://discourse.julialang.org/u/WenlongGong)\
**Post date:** [April 17, 2017, 3:09am UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/11 "2017-04-17T03:09:51Z")

</div>

I tried the pointer\_to\_array(ptr,dims,true) but that didn’t solve the problem of accumulating memory.

In the help docs about calling-c-and-fortran-code. It says “If the pointer of interest is a plain-data array (bitstype or immutable), the function pointer\_to\_array(ptr,dims,[own]) may be more useful. The final parameter should be true if Julia should “take ownership” of the underlying buffer and call free(ptr) when the returned Array object is finalized.”

However, calling free(ptr) afterwards gives ERROR: UndefVarError: free not defined. Does julia call this free(ptr) by itself, or an explicit gc() could do the work?

Thank you for your help!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 17, 2017, 11:53am UTC](https://discourse.julialang.org/t/accumulating-memory-in-nested-loops/3220/12 "2017-04-17T11:53:44Z")

</div>

Julia calls `free` itself once the array is garbage-collected.

Alternatively, you can use `pointer_to_array(ptr,dims,false)` to retain ownership of the pointer, can call `Libc.free(ptr)` yourself once you are done with it.
