Erlang - Looping and Memory Allocation - memory-management

The typical way to make a loop for a process in Erlang is to use recursion:
keepAlive(someArg) ->
% do something,
keepAlive(someValue)
Since variables in Erlang are immutable, what happens when I declare a local variable inside such a loop? Does it get garbage collected on the next recursive call? Even without a declaration of new variables, aren't loops like this a problem and can cause a stackoverflow, because you get an endless number of pointers, from one loop to another, that theoretically might have to go all the way back at some point?

Technically speaking, local variables are not declared in Erlang. They are bound to value. Values of local variables are stored on the stack. Some data types could be stored directly in the stack and don't have to be allocated on the heap. So local variables don't have to be garbage collected but values of some data types have to be. Anyway, those values are not garbage collected in next recursive call but when heap meets stack which means heap is full and garbage collection is triggered.
Most importantly, if you write a function in the way you described stack frame is freed before the recursive call and parameter is stored in "registers". Then next recursive call is not function call but just jump. It means stack doesn't grow. All values which were allocated on the heap and no longer referenced by stack or function parameters can be garbage collected so there is not memory leak or stack overflow. In fact, it is very simple and elegant solution.

Related

Can I force a value that never escapes a subroutine to be stored on the heap in Go? [duplicate]

I am new to Go, and found it is OK to return the address of a local variable defined in a function. That is obviously not possible in C since local variable is in stack.
So I am just wondering why it is OK to do it in Go? In Go, the local variable is in heap? Will it affect performance since allocating heap memory is quite expensive than stack? Is it possible allocate local variable in stack in Go? Or actually is there stack memory in Go?
There's a very clear answer to that question in the FAQ:
How do I know whether a variable is allocated on the heap or the
stack?
From a correctness standpoint, you don't need to know. Each variable
in Go exists as long as there are references to it. The storage
location chosen by the implementation is irrelevant to the semantics
of the language.
The storage location does have an effect on writing efficient
programs. When possible, the Go compilers will allocate variables that
are local to a function in that function's stack frame. However, if
the compiler cannot prove that the variable is not referenced after
the function returns, then the compiler must allocate the variable on
the garbage-collected heap to avoid dangling pointer errors. Also, if
a local variable is very large, it might make more sense to store it
on the heap rather than the stack.
In the current compilers, if a variable has its address taken, that
variable is a candidate for allocation on the heap. However, a basic
escape analysis recognizes some cases when such variables will not
live past the return from the function and can reside on the stack.
TLDR: You shouldn't care. Go takes care of allocation for you.

How does gc Go handle heap allocation?

Does gc Go (specifically go1.11) pre-allocates a chunk of memory and take from it for each allocation (like JVM), or it allocates every time a variable is created, and is it a kernel call (malloc)?
If it is one kernel call per allocation, that would make variable creation expensive. How can I force allocation on the stack/heap?
This is covered in various places, like the FAQ:
How do I know whether a variable is allocated on the heap or the stack?
From a correctness standpoint, you don't need to know. Each variable
in Go exists as long as there are references to it. The storage
location chosen by the implementation is irrelevant to the semantics
of the language.
The storage location does have an effect on writing efficient
programs. When possible, the Go compilers will allocate variables that
are local to a function in that function's stack frame. However, if
the compiler cannot prove that the variable is not referenced after
the function returns, then the compiler must allocate the variable on
the garbage-collected heap to avoid dangling pointer errors. Also, if
a local variable is very large, it might make more sense to store it
on the heap rather than the stack.
In the current compilers, if a variable has its address taken, that
variable is a candidate for allocation on the heap. However, a basic
escape analysis recognizes some cases when such variables will not
live past the return from the function and can reside on the stack.
Go's memory allocation is carefully optimized for its needs, for example with a custom malloc. I suspect you have a slightly different underlying question/problem that you're struggling with - it would be better to ask that instead. If this is just exploration/curiosity, you'll have to make your question much more specific.

Why dose go store value of pointer semantics on the heap?

William Kennedy(author of go in action) said that In go, there are two semantics. Value semantics, which stored on stack, mean that we’re making a copy of the value as we go across these program boundaries. Pointer semantics, which stored on heap, mean that we’re sharing the value as we go across there program boundaries. Garbage collector will kick in sometimes to recycle the unused memory on heap. I want to know why the values of pointer semantics are stored on heap. Could you explain?
Anytime a value is shared outside the scope of a function’s stack frame, it will be placed (or allocated) on the heap. It’s the job of the escape analysis algorithms to find these situations and maintain a level of integrity in the program. The integrity is in making sure that access to any value is always accurate, consistent and efficient.
Reference: https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html

What is the Space Complexity of Passing by Reference

I was reading this website to learn about space complexity. It mentioned the following scenario:
A function is written in a language that is pass by value. So whenever an argument is passed, new memory is allocated for the local variable. However, you pass a pointer to a variable instead, so you are passing by reference.
The website said that this would not allocate new space for a local variable, because you are passing by reference, so the variable already exists in memory, and the memory is then shared.
But wouldn't it still create a local variable that was a pointer to the memory location? And, as a result, allocate new memory?
Yes; there is a single word of memory allocated in the stack frame for that call. What they intend to convey is that you're not allocating memory for the existing variable (e.g. 1kb for a 1000-character string). Formally, this allocation is O(1) rather than the O(n) you get from pass by value.
If you don't consider the stack to be part of the process's memory, then you have a zero-cost allocation for this case. Also, note that O(1) space overhead will not increase the complexity for any algorithm, so it's theoretically okay to ignore. It's valid, although it does smell strange to do so.
I don't much about space complexity but references are normally passed on the stack. Some systems hold this entirely in a register especially if the function is in lined and hence no memory allocation.
Also note huge difference between register , stack and heap in terms of performance , safety etc.

Are all the variables in Go allocated on heap?

I am new to Go, and found it is OK to return the address of a local variable defined in a function. That is obviously not possible in C since local variable is in stack.
So I am just wondering why it is OK to do it in Go? In Go, the local variable is in heap? Will it affect performance since allocating heap memory is quite expensive than stack? Is it possible allocate local variable in stack in Go? Or actually is there stack memory in Go?
There's a very clear answer to that question in the FAQ:
How do I know whether a variable is allocated on the heap or the
stack?
From a correctness standpoint, you don't need to know. Each variable
in Go exists as long as there are references to it. The storage
location chosen by the implementation is irrelevant to the semantics
of the language.
The storage location does have an effect on writing efficient
programs. When possible, the Go compilers will allocate variables that
are local to a function in that function's stack frame. However, if
the compiler cannot prove that the variable is not referenced after
the function returns, then the compiler must allocate the variable on
the garbage-collected heap to avoid dangling pointer errors. Also, if
a local variable is very large, it might make more sense to store it
on the heap rather than the stack.
In the current compilers, if a variable has its address taken, that
variable is a candidate for allocation on the heap. However, a basic
escape analysis recognizes some cases when such variables will not
live past the return from the function and can reside on the stack.
TLDR: You shouldn't care. Go takes care of allocation for you.

Resources