Performant Programming Series: Memory Management (Part 1)
Judiciously managing computing resources is an important aspect of programming. Even in the world of cloud computing where resources are elastic they are still expensive.
By definition any physical or virtual component of limited availability within a computer system is called a computing resource. This includes compute resources (CPU), networking resources(sockets, bandwidth), memory resources( RAM, virtual memory), storage resources(hard disks). These resources are often shared between different processes running on the computer.
While there are a lot of interesting things to discuss about resource management, this article focuses on aspects of memory management that we as programmers control. Memory management happens at the hardware layer, the operating system layer and the application layer. The responsibility and hence control that a programmer has on managing its program’s memory differs across programming languages. For example, in C, where there is no garbage collector, the programmer must allocate and free memory explicitly while the same is not needed in Python. However, irrespective of the programming language being used developers should be well aware of how memory is being managed by the underlying infrastructure to develop truly performant systems.
We will now see how memory is layed out in a C/C++ program. A typical memory representation of C program consists of following sections.
- Stack : This LIFO (Last In First Out) data structure is used to store all temporary variables declared in a function (push), when the function exits all the variables which were pushed into the stack are freed (pop). And now we know how infinite recursion leads to stack overflow error !
- Heap : This is a free flowing section of the memory where programmers can allocate memory to variables at run time, there are no scope or size limitations on the memory allocated here. However, programmers are responsible to deallocate the memory in a heap, else it could lead to memory leaks.
- BSS : This segment contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code. Data in this segment is initialized by the OS kernel to arithmetic 0 before the program starts executing.
- Data : This segment contains any global or static variables which have a pre-defined value and can be modified. These variables are either not defined within a function or are defined within a function but with a static keyword. This means that they need to retain their values across function calls and hence they cannot be a part of the stack.
- Text : This is a read only, fixed sized segment which contains executable instructions of the program.
Now that we know how memory is organised in C programs, in the next part of the series we will discuss some common memory errors and good coding practices to avoid them.
Follow us for more such articles, you can also visit addskill.io to know more about us.