Application of heap and stack in IOS development

Time:2020-8-3

Heap and stack are data structures in which data items are arranged in order. Data items can only be inserted and deleted at one end (called top of stack).

FIFO first in first out;

FIFO first in / last out.

Generally speaking, if someone put the stack together, it means stack, not stack.

Stack space allocation

1. Stack: it is automatically allocated and released by the compiler to store function parameter values and local variable equivalence. Its operation is similar to the stack in the data structure.

2. Heap: it is generally allocated and released by the programmer. If the programmer does not release it, it may cause memory leakage. It is similar to a linked list.

Stack cache mode

The computer memory used by applications in IOS is not uniformly allocated space. The space used for running code is divided into three sections: “text segment”, “stack segment” and “heap segment”.

Text segment:

It is the memory segment that exists in the application code when the application is running. It has been determined before running (determined at compile time). It is usually read-only. The instructions in the code area include the operation code and the object to be operated (or object address reference). The instructions in the code area are executed in sequence according to the programming flow. Each instruction, each single function, procedure, method and execution code are stored in this memory segment until the application program exits. It is rarely involved in general use.

Stack:

When we create a value type, such as a structure, the system stores it in a memory area called a stack, which is directly managed and optimized by the CPU. When a function declares a variable, the variable will be stored in the stack. When the function is called, the stack will release the variable automatically. Therefore, the stack is very easy to manage and effective, because it is directly controlled by the CPU, the speed is very fast.

Heap:

When we create a reference type, such as a class, the system stores the class instance in a memory area called the heap. The system uses the heap to store data referenced by other objects.

The heap is a large memory pool from which the system can request and dynamically allocate memory blocks. The heap does not automatically release objects like a stack, and extra work is required. This makes creating and deleting data in the heap slower than the stack.

The stack uses the first level cache. They are usually in the storage space when they are called and are released immediately after the call.

The heap is stored in the secondary cache, and its life cycle is determined by the garbage collection algorithm of the virtual machine (not once orphaned objects can be recycled). So the speed of calling these objects is relatively low.

A pointer in the stack is just an integer variable that holds the data of a specific memory address in the heap. In short, the operating system uses the pointer value in the stack segment to access the objects in the heap segment. If there is no pointer to the stack object, the object in the heap cannot be accessed. This is also the cause of memory leaks.

You can create data objects in both stack and heap segments of IOS.
Stack object has two advantages, one is to create fast, the other is simple management, it has a strict life cycle. The disadvantage of the stack object is that it is inflexible. As long as it is created, it is always owned by the function that created it. Unlike a heap object with multiple owners, multiple owners are equivalent to reference counting. Only the heap object is managed by the “reference count” method.

As a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my IOS communication group: 519832104, no matter you are Xiaobai or Danio, welcome to settle in, share experience, discuss technology, and communicate with each other, learn and grow together!

Also attached is a large factory interview questions collected by friends. You need IOS development learning materials and real interview questions. You can add IOS development advanced communication group and download it by yourself!

Stack data structure differences

Heap (data structure): the heap can be considered as a tree, such as heap sorting.

Stack (data structure): a data structure that comes in and out later.

What is the difference between heap and stack? The main differences are as follows:

1. Different management methods;

Management mode: for the stack, it is automatically managed by the compiler, without manual control; for the heap, the release is controlled by the programmer, which is easy to generate memory leak.

2. The space size is different;

Space size: a stack is a small but fast memory area. The memory allocation on the stack follows the principle of last in first out. The push and pop operations are implemented by moving the tail pointer of the stack. Our program is composed of methods, and the CPU is responsible for scheduling and executing these methods. When our program runs to a certain method, we need to open up space on the stack for the memory needed by the method. At this time, we move the tail pointer of the stack to the bottom of the stack. After the method is executed, the space needs to be released. At this time, the tail pointer of the stack will be moved to the top of the stack, which completes the memory allocation on the stack. As long as the remaining space of the stack is greater than the space created by the stack object, the operating system will provide this memory space for the program. Otherwise, an exception will be reported to prompt the stack overflow.

The heap is another area of memory that is much larger than the stack, but runs slower than the stack. Heap can dynamically allocate memory at run time to make up for the lack of memory allocation on the stack. Generally speaking, heap memory can reach 4G in a 32-bit system. From this point of view, heap memory is almost unlimited.

The operating system uses linked list to manage the memory heap segment. The operating system has a linked list to record the address of the free memory. When receiving the application from the program, it will traverse the list to find the first heap node whose space is larger than the requested heap node, and then delete the node from the free node list and allocate the space of the node to the program. IOS uses a technology called arc (automatic reference counting). In a multithreaded environment, multiple threads will share the memory on the heap. In order to ensure thread safety, we have to lock the heap. However, locking is very expensive. The data security you get on the heap is actually obtained at the cost of performance.

3. Whether fragments can be produced is different;

Fragmentation: for the heap, frequent new / delete will inevitably cause the discontinuity of memory space, resulting in a large number of fragments, which will reduce the efficiency of the program. For the stack, there is no such problem, because the stack is a queue of first in and last out. They are so one-to-one corresponding that it is impossible for a memory block to pop out from the middle of the stack. Before the stack pops up, the contents of the backward stack above it have been ejected.

4. The growth direction is different;

Growth direction: for heap, the growth direction is upward, that is, toward the direction of increasing memory address; for stack, its growth direction is downward, which is toward the direction of decreasing memory address.

5. The distribution mode is different;

Allocation method: the heap is dynamically allocated and there is no statically allocated heap. There are two ways of stack allocation: static allocation and dynamic allocation. Static allocation is done by the compiler, such as the allocation of local variables. Dynamic allocation is allocated by the alloca function, but the dynamic allocation of stack is different from that of heap. Its dynamic allocation is released by the compiler and does not need to be implemented manually.

6. The distribution efficiency is different;

Allocation efficiency: the stack is a data structure provided by the machine system, and the computer will provide support for the stack at the bottom layer: assign special registers to store the stack address, and there are special instructions to execute when pressing the stack out of the stack, which determines the higher efficiency of the stack. The heap is provided by the C / C + + function library, and its mechanism is very complex. For example, in order to allocate a block of memory, the library function will be in the heap according to a certain algorithm (the specific algorithm can refer to the data structure / operating system) Search the available space of enough size in memory. If there is not enough space (possibly due to too many memory fragments), it is possible to call the system function to increase the memory space of program data segment. In this way, it is possible to allocate enough memory and then return. Obviously, heaps are much less efficient than stacks.

From here, we can see that compared with the stack, heap is easy to cause a large number of memory fragments due to the use of a large number of new / delete; due to the lack of special system support, the efficiency is very low; due to the possible switch between user mode and core state, the cost of memory application becomes more expensive.

So stack is the most widely used in the program, even if the function call also uses the stack to complete, function call process parameters, return address, local variables are stored in the way of stack.

However, the disadvantage is that the size and lifetime of the data in the stack must be fixed, which lacks flexibility. In addition, stack data cannot be shared among multiple threads or stacks, but multiple variables with equal values can point to an address within the stack. Compared with heap, it is not so flexible. Sometimes it is better to use heap to allocate a large amount of memory space. Whether it is heap or stack, we should prevent the occurrence of cross-border phenomenon (unless you deliberately make it cross-border), because the result of cross-border is either the program crash, or destroy the heap and stack structure of the program, resulting in unexpected results. Even if the above problem does not occur in the process of running your program, you should be careful, and it may collapse at some time.

Use in swift

The data types in swift are divided into reference type (class) and value type (enumeration and structure). Reference types are stored on the heap and value types are stored on the stack. Swift uses the automatic reference counting (ARC) management method to manage reference types. Value types are managed by the processor and do not need to be managed by the programmer.

In swift, struct, enum, and tuple are typical value types. In fact, int, double, float, string, array, dictionary and set are implemented with structs, which are also value types. In swift, the value type is assigned as deep copy. The value semantics means that the new object and the source object are independent. When the properties of the new object are changed, the source object will not be affected. Otherwise, the same is true.

In swift, classes and closures are reference types. The assignment of reference type is shallow copy. Reference semantics means that the variable names of the new object and the source object are different, but their references (pointing to the memory space) are the same. Therefore, when the new object is used to manipulate its internal data, the internal data of the source object will also be affected.

When a value type is passed in as a parameter, its value cannot be modified inside the function body. When a reference type is passed in as a parameter, the memory address it points to cannot be modified inside the function body, but the variable value inside the function body can be modified.

The advantages of value type are: invariance, the variable of value type is strictly controlled by an owner; independence, reference type is interdependent, which is an implicit dependency; and interchangeability.

For object-oriented programming, because the instance object is variable, the other owner of the object will change the property of the object when appropriate. Swift supports single inheritance of classes, which leads to inheritance from multiple classes to more functions, increases the complexity, and leads to the problem of tight coupling of classes. In the case of multithreading, the same reference can be changed at the same time.

One of the main reasons for choosing value types over reference types is that it makes your code simpler. The core of swift is protocol oriented, and reference types have many owners. The value type is assigned to a variable or constant, and its value is copied when it is passed to a function as a parameter. This reduces the complexity by making the value type have only one owner at any time. In any case, if you use a value type, you can assume that your other code will not change it. This is usually useful in a multi-threaded environment. If the data used in one thread is accidentally modified by another thread, it usually generates very serious bugs and is quite difficult to debug. Class = high complexity, value = low complexity. Moreover, swift optimizes the operation of value type, so it is said that swift uses value type instead of reference type.

Because the difference is only reflected when you need to modify the data, when your instance does not modify the data, the value type and reference type look exactly the same. You may want to write a completely immutable class to implement an immutable class in swift by using immutable storage properties and avoiding exposing interfaces that modify data. In fact, most cocoa classes, such as nsurl, are designed to be immutable. However, swift does not provide any language mechanism to force a class to be immutable (for example, subclassing can modify the implementation of a class). Only structs and lobes are mandatory immutable.

In swift, array, string and dictionary are value types. Their behavior is similar to int in C language. Each instance has its own data. You don’t need to do anything extra, such as making an explicit copy to prevent other code from being modified without your knowledge. More importantly, you can safely pass it between programs without using synchronization technology 。 In the spirit of improving security, this model will help you write more predictable code in swift.

In addition, swift and OC have other types corresponding, and the corresponding relationship is as follows:

However, it should be noted that for the reference type of the original OC data, swift does not really fully implement a set of data storage logic. Only the reference to OC object is saved internally, which makes the behavior logic and value type consistent when accessing swift API

Click here to communicate with IOS Daniel immediately