How does SVector manage memory?

julia> using StaticArrays

julia> using BenchmarkTools

julia> x = [1, 2, 3]
julia> y = SVector{3, Int64}(x)

julia> @btime exp.($x);
  62.574 ns (1 allocation: 112 bytes)
julia> @btime exp.($y);
  0.022 ns (0 allocations: 0 bytes)

showing SVector uses zero memory. As far as I understand, SVector uses “stack memory” while Vector uses “heap memory”. But they’re both memories (i.e. using RAM), how could @btime report 0 bytes?!
also, I read that using “stack memory” could “avoid the expensive garbage collection”. These rise the following questions:

  1. why using stack memory is faster than heap memory (apart from the time in gc)?
  2. why @btime reports fewer (or even zero) memory usage when stack memory is used?
  3. does stack memory have any mechanism for garbage collection? if yes, could we control the gc?
  4. if 3. is no, does it imply that creating (even small) SVector over millions of iterations would inevitably run out of the stack memory?

many thanks.

You can find general (not Julia-specific) descriptions of stacks to answer all of your questions, eg

GC does not apply (conceptually). Also, for LLVM, the actual objects may just be in registers etc when small, not in RAM.

As for (4), it depends on how you get those million objects on the stack. Eg if you are recursively calling functions that do this, you may experience problems. This is not what the stack is for.

1 Like

fortunately it’s not what I do.

By the way, whenever running out of stack memory, what would StaticArrays (or Julia) do? Would they be smart enough to switch to heap memory?

You get a stack overflow.

You should design your algorithms so that this does not happen.

according to the wiki you posted above:

memory on the stack is automatically, and very efficiently, reclaimed when the function exits

is it also true for StaticArrays or Julia in general? I’m just a bit uncomfortable switching to SVector as I have no idea how large the “stack memory” is and I have no control over “gc”…

Again, this is only relevant if you are doing very deep recursions (or, possibly, your static vectors are huge, but then you should not use them anyway). This should not be a concern for idiomatic Julia code, with or without static vectors.

@tomtom: let me give you two answers and you choose which one applies best to your situation:

  1. Practical answer: Yes, Julia(/LLVM) is smart enough to allocate largish structures on the heap instead of the stack. The exact threshold is an implementation detail (it may even keep it in registers, etc). So as a language user, you don’t really have to worry about it. Just use SVectors and measure if you are getting better timings.

  2. Theoretical answer: if you want to know exactly what’s going on, you’d have to start with actually understanding registers, stack, heap, and calling conventions. If that’s what you want, Julia is not the best place to start: it’s actually better to study the C language for a bit, and see how it manages memory. If that’s what you want, this one looks pretty good (bit I haven’t read it fully).