# Memory allocation and @profile

**URL:** https://discourse.julialang.org/t/memory-allocation-and-profile/47573
**Category:** Performance
**Created:** [October 1, 2020, 7:23am UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573 "2020-10-01T07:23:06Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Ross\_Boylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ross_boylan/32/9210_2.png) [@Ross\_Boylan](https://discourse.julialang.org/u/Ross_Boylan)
#### Post date: [October 1, 2020, 7:23am UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/1 "2020-10-01T07:23:06Z")

</div>

`@time` shows that my program is doing a lot of memory allocation, much of which I could probably avoid. For example

```julia
@time b2 = MyFirst.mysolve(f2, nhsub, nhsub.wtfast16yr)
1.998780 seconds (6.27 M allocations: 479.828 MiB, 2.69% gc time)

```

I’m trying to understand where it’s happening and how much of the time it’s taking. The gc time seems relatively small, but I assume memory allocation takes time too.

The hierarchical `Profile.print()` has a left-most column labelled Overhead. What is this supposed to represent? Memory allocation time? JIT time? sampler time?

[Profiling · The Julia Language](https://docs.julialang.org/en/v1.5/manual/profile/) does not discuss the Overhead column, and the sample outputs there don’t even include it.

That same page does say

> specific lines triggering allocation can often be inferred from profiling via the cost of garbage collection that these lines incur.

How exactly can one tell the cost of garbage collection? Is it the overhead field? Will it appear as an explicit call in the profile stack?

More substantively, I thought the places and time gc was triggered were somewhat random, and not necessarily the place the memory was allocated.

And, to repeat, what if I want to measure allocation directly? Do I need to go to the `--track-allocation` option, which apparently requires a restart of Julia?

I’m using Julia 1.5.1 on MS Windows 10.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [October 1, 2020, 8:28am UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/2 "2020-10-01T08:28:29Z")

</div>

> [@Ross\_Boylan](#):
>
> Will it appear as an explicit call in the profile stack?

You would only see allocations there. GC only happens as pat of those (possibly). If you have many threads I believe you could have no allocations, except in some other thread you’re not tracking and it would slow down doing GC.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 1, 2020, 12:47pm UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/3 "2020-10-01T12:47:57Z")

</div>

> [@Ross\_Boylan](#):
>
> How exactly can one tell the cost of garbage collection? Is it the overhead field? Will it appear as an explicit call in the profile stack?
> 
> More substantively, I thought the places and time gc was triggered were somewhat random, and not necessarily the place the memory was allocated.

You are right, it is stochastic so you need to run many times. I usually rely on BenchmarkTools to do this:

```julia
julia> using BenchmarkTools

julia> silly_example() = sum(randn(1000))
silly_example (generic function with 1 method)

julia> @benchmark silly_example()
BenchmarkTools.Trial: 
  memory estimate: 7.94 KiB
  allocs estimate: 1
  --------------
  minimum time: 3.347 μs (0.00% GC)
  median time: 3.903 μs (0.00% GC)
  mean time: 4.679 μs (10.34% GC)
  maximum time: 428.693 μs (92.27% GC)
  --------------
  samples: 10000
  evals/sample: 8

```

---

<div class="post-metadata">

### Author: ![Ross\_Boylan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ross_boylan/32/9210_2.png) [@Ross\_Boylan](https://discourse.julialang.org/u/Ross_Boylan)
#### Post date: [October 1, 2020, 11:16pm UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/4 "2020-10-01T23:16:13Z")

</div>

I don’t see anything that looks like a call to memory allocation in my profile. Possibilities:

1. I don’t know what to look for.
2. It is too infrequent to have been caught by my threshholds (see below).
3. I need to enable tracing into C.

I looked at the profile with

```julia
Profile.print(; maxdepth=25, noisefloor=5)
Profile.print(;format=:flat, mincount=1000)

```

There were about 57k top level samples

Also, I’m still hoping someone can explain what the overhead column is in the default (tree) profile print.

---

<div class="post-metadata">

### Author: ![mtsch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mtsch/32/2072_2.png) [@mtsch](https://discourse.julialang.org/u/mtsch)
#### Post date: [October 1, 2020, 11:57pm UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/5 "2020-10-01T23:57:48Z")

</div>

I can’t help you with the overhead column (I never use `Profile.print`), but I would recommend trying to view profiles with [ProfileView.jl](https://github.com/timholy/ProfileView.jl). In my opinion, it’s much easier to look at than `Profile.print`.

When viewing the profile, look for orange and red bars. The orange ones show where allocations happen and the red ones show where dynamic dispatch happens. Dynamic dispatch can also be a source of allocations and can sometimes be very bad for performance.

Since your function only takes about two seconds to complete, maybe try running it a few times to get a better view of the profile.

---

<div class="post-metadata">

### Author: ![mikkoku](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikkoku/32/16274_2.png) [@mikkoku](https://discourse.julialang.org/u/mikkoku)
#### Post date: [October 8, 2020, 2:24pm UTC](https://discourse.julialang.org/t/memory-allocation-and-profile/47573/6 "2020-10-08T14:24:42Z")

</div>

What do I do to find out memory allocations?

1. `@profiler` (I’m using Juno) has same colors as ProfileView.jl. Doesn’t directly show allocations but if the allocations result in slow code, profiling should help focus the search.
2. `@code_warntype` to find memory allocations related to type-instability.
3. for `--track-allocation` I write a script like

```julia
function g(n, T)
    sum([rand(T) for _ in 1:n])
end
@time g(1, Float64)
using Profile
Profile.clear_malloc_data()
@time g(100, Float64)
exit()
file = @ __FILE__
run(`julia --track-allocation=user $file`)

```

The last lines are because I’m using Juno and too lazy to open a terminal.

1. Sprinkle `@time` inside the suspicious function to see if the allocations also result in time spent. This only works in one level at a time because `@time @time` results in many allocations. Somehow this is the most precise method I know to measure memory allocations.
