# Combining reshape and view sometimes allocates

**URL:** <https://discourse.julialang.org/t/combining-reshape-and-view-sometimes-allocates/135725>\
**Category:** Performance\
**Tags:** array, memory-allocation, views\
**Created:** [February 19, 2026, 6:38am UTC](https://discourse.julialang.org/t/combining-reshape-and-view-sometimes-allocates/135725 "2026-02-19T06:38:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [February 19, 2026, 6:38am UTC](https://discourse.julialang.org/t/combining-reshape-and-view-sometimes-allocates/135725/1 "2026-02-19T06:38:52Z")

</div>

I have some complicated code that uses a combination of `reshape()` and `view()`, and in my complicated code both `reshape()` and `view()` allocates. Trying to reduce my code to an MRE, I came up with this:

```julia
function profile_allocs()
    x = randn(6)
    Profile.Allocs.clear()
    Profile.Allocs.@profile sample_rate=1.0 begin
        x = reshape(x, (3,2))
        sum(view(x, :))
    end
    Profile.Allocs.print()
end

```

On 1.11.9, this allocates:

```julia-auto
julia> profile_allocs()
Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
  # ...
  ╎ ╎ ╎ 32 REPL[2]:4; profile_allocs()
  ╎ ╎ ╎ 32 @Profile/src/Allocs.jl:82; macro expansion
  ╎ ╎ ╎ 32 REPL[2]:6; macro expansion
  ╎ ╎ ╎ ╎ 32 @Base/subarray.jl:216; view
  ╎ ╎ ╎ ╎ 32 @Base/subarray.jl:156; _maybe_reshape_parent
  ╎ ╎ ╎ ╎ 32 @Base/reshapedarray.jl:152; reshape
  ╎ ╎ ╎ ╎ 32 @Base/reshapedarray.jl:121; reshape
32╎ ╎ ╎ ╎ 32 @Base/reshapedarray.jl:60; reshape
Total snapshots: 1
Total bytes: 32

```

On 1.12.5, this does not allocate:

```julia-auto
julia> profile_allocs()
Overhead ╎ [+additional indent] Count File:Line Function
=========================================================
┌ Warning: There were no samples collected.
│ Run your program longer (perhaps by running it multiple times),
│ or adjust the frequency of samples to record every event with
│ the `sample_rate=1.0` kwarg.
└ @ Profile.Allocs ~/.julia/juliaup/julia-1.12.5+0.aarch64.apple.darwin14/Julia-1.12.app/Contents/Resources/julia/share/julia/stdlib/v1.12/Profile/src/Allocs.jl:226

```

I guess my primary objective here is trying to understand why v1.11 allocates, but anything that sheds some light on Julia’s current allocation behaviour will probably be useful.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 19, 2026, 2:27pm UTC](https://discourse.julialang.org/t/combining-reshape-and-view-sometimes-allocates/135725/2 "2026-02-19T14:27:15Z")

</div>

This looks like [reshape(::Array, ...) is slow and allocates · Issue #36313 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/36313), but with 1.12’s extra smarts about escape analysis saving it from getting there.

Basically, it’s not allocating the whole new array. It’s still a view. It just needs an extra heap-allocated header that describes the new dimensions.

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [February 20, 2026, 2:31am UTC](https://discourse.julialang.org/t/combining-reshape-and-view-sometimes-allocates/135725/3 "2026-02-20T02:31:05Z")

</div>

Ah, so the problem is that `Array`’s implementation is roughly equivalent to

```julia
mutable struct Array{T, N}
    data::Memory{T}
    dims::NTuple{N, Int}
end

```

and therefore `reshape()` technically must always allocate a new such `Array` object. The “miracle” is that most of the time it doesn’t, because the compiler can prove that this new `Array` object has a bounded lifetime and therefore doesn’t need heap allocation. That makes perfect sense, I was just confused by the fact that `reshape()` doesn’t allocate most of the time. That made me think that the above example must be exceptionally bad in some ways, but really the point is that most uses of `reshape()` are exceptionally “good” for not needing allocation due to successful escape analysis.
