# Why do \`@allocated\` and \`Profile.Allocs.@profile\` give different results?

**URL:** <https://discourse.julialang.org/t/why-do-allocated-and-profile-allocs-profile-give-different-results/134956>\
**Category:** Performance\
**Tags:** memory-allocation, profiling\
**Created:** [January 8, 2026, 4:52pm UTC](https://discourse.julialang.org/t/why-do-allocated-and-profile-allocs-profile-give-different-results/134956 "2026-01-08T16:52:04Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [January 8, 2026, 4:52pm UTC](https://discourse.julialang.org/t/why-do-allocated-and-profile-allocs-profile-give-different-results/134956/1 "2026-01-08T16:52:04Z")

</div>

The number of allocations reported by `Profile.Allocs.@profile` agrees with `@allocations`, but the total number of bytes allocated differs from `@allocated` for some reason:

```julia-auto
using Profile.Allocs

f(n) = sum(2*collect(1:n))

function g(n)
    println(@allocations(f(n)), " allocs: ", @allocated(f(n)), " bytes")
    Allocs.clear()
    Allocs.@profile sample_rate = 1.0 f(n)
    allocs = Allocs.fetch().allocs
    b = sum(a -> a.size, allocs)
    println(length(allocs), " allocs: ", b, " bytes")
end

```

gives

```julia-auto
julia> g(1)
4 allocs: 128 bytes
4 allocs: 112 bytes

julia> g(2)
4 allocs: 160 bytes
4 allocs: 128 bytes

julia> g(100)
4 allocs: 1856 bytes
4 allocs: 1696 bytes

```

What’s the reason for this discrepancy?

(Tested on Julia 1.11.8, 1.12.4 and 1.13.0-alpha2.)

---

<div class="post-metadata">

**Author:** ![Tyrone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tyrone/32/221141_2.png) [@Tyrone](https://discourse.julialang.org/u/Tyrone)\
**Post date:** [March 10, 2026, 2:52pm UTC](https://discourse.julialang.org/t/why-do-allocated-and-profile-allocs-profile-give-different-results/134956/2 "2026-03-10T14:52:52Z")

</div>

This is because Profile.Allocs.@profile returns the actual object size and @allocated returns the size it occupies in memory (Pool size)

Detailed technical answer, take the following input:

```julia-auto
julia> g(1) 
4 allocs: 128 bytes
4 allocs: 112 bytes

julia> g(2)
4 allocs: 160 bytes
4 allocs: 128 bytes

julia> g(3)
4 allocs: 160 bytes
4 allocs: 144 bytes

```

Objects have to fit in a specific “pool” in memory, this is why @allocated reports the same memory for for `g(2)` and `g(3)` (160 bytes) as the result still fits in the same pool.

I also used CodeGlass to find out what was being allocated. It found:

```julia-auto
In REPL function f(n):
Array{Int64,1} (always 32 bytes)
Int64[] (8*n bytes + 16 bytes for array header)

In arraymath.jl:21 function *(A::Int64, B::Array{Int64, 1})::Array{Int64, 1}
Array{ Int64,1} (always 32 bytes)
Int64[] (8*n bytes + 16 bytes for array header)

```

Julia uses the the following pool sizes that are relevant to this question ([julia\_internal.h:436](https://github.com/JuliaLang/julia/blob/5fe89b8ddc166260bfcd4a195b305aff0ccad686/src/julia_internal.h#L436))

```julia-auto
// 16 pools at 8-byte spacing
// the 8-byte aligned pools are only used for Strings
16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136,

```

Since it is not a string, it must fit the Int64 bodies into 16 bytes aligned pools, so not in the 24 bytes pool but in the 32 bytes, so for example:

```julia-auto

g(1) Allocations:
1x Array{Int64,1} = 32 bytes = 32 bytes in pool
1x Array{Int64,1} = 32 bytes = 32 bytes in pool
1x Int64[] = 8*1+16 = 24 bytes = 32 bytes in pool
1x Int64[] = 8*1+16 = 24 bytes = 32 bytes in pool
Total actual object size: 112 bytes (Reported by Profile.Allocs.@profile)
Total size in pool : 128 bytes (Reported by @allocated)

```

I hope this was helpful 🙂
