Memory Management

In this doc we will talk about memory management in iOS and other operating systems.

Stack and Heap

1. Stack

The stack is a region of memory that is used to store local variables and function call information. It is a LIFO (Last In First Out) data structure, which means that the last item pushed onto the stack is the first item popped off the stack.

The stack is managed automatically by the operating system, and memory is allocated and deallocated in a strict order. When a function is called, the local variables for that function are pushed onto the stack, and when the function returns, the stack is popped, and the memory is deallocated.

The stack is fast and efficient because memory allocation and deallocation are done in a strict order, and the memory is automatically managed by the operating system.

2. Heap

The heap is a region of memory that is used to store dynamically allocated memory. It is a more flexible data structure than the stack because memory can be allocated and deallocated in any order.

The heap is managed manually by the programmer, and memory must be explicitly allocated and deallocated. Memory allocated on the heap must be explicitly deallocated to prevent memory leaks.

The heap is slower and less efficient than the stack because memory allocation and deallocation can be done in any order, and the memory must be managed manually by the programmer.

3. Stack vs Heap

  • Stack:

    • Fast and efficient
    • Memory is automatically managed by the operating system
    • Memory allocation and deallocation are done in a strict order
    • Local variables and function call information are stored on the stack
  • Heap:

    • Slower and less efficient
    • Memory must be manually managed by the programmer
    • Memory allocation and deallocation can be done in any order
    • Dynamically allocated memory is stored on the heap

函数存储在栈内存中,而闭包存储在堆内存中。这是因为函数是静态的,而闭包是动态的。函数的内存布局在编译时就已经确定,而闭包的内存布局在运行时才能确定。因此,函数的内存布局可以在栈上分配,而闭包的内存布局必须在堆上分配。
栈内存:函数的局部变量、参数以及函数调用信息(如返回地址)存储在栈内存中。栈内存是LIFO(后进先出)结构,当函数调用结束时,栈顶的内存会自动释放。栈内存管理速度快,但内存空间有限。
堆内存:堆内存用于动态分配的内存,例如闭包、对象等。堆内存需要手动管理(如通过引用计数或垃圾回收机制)。堆内存适用于需要长时间存活或大小不确定的数据,但分配和释放的速度比栈内存慢一些。
e.g. 当一个闭包需要在函数返回后继续存在并被调用时,需要将闭包存储在堆内存中,这样可以确保它在函数返回后依然有效。

This is why escaping is needed when a closure is stored in a property or passed as an argument to another function. The closure needs to be stored on the heap to ensure that it is still valid after the function returns.

Also, autoclosure is a way to delay the evaluation of an expression, which means the expression is stored on the heap and evaluated only when it is needed. The execution of the expression is delayed until it is needed, which can improve performance and reduce memory usage.