Hey there! It’s been a while since i’ve written an article. Finally allocated some time to spear here :D
What is a RAM?
So, lets start by talking, whats a RAM?
Random-access memory (RAM) is a form of electronic computer memory that can be read and changed in any order, typically used to store working data and machine code. -wiki
in simple words, it stores our machine code, and helps CPU to execute it. In modern operating system, the RAM logically divides into two distinct region; KERNEL SPACE and User Space .
What is Kernel Space?
Kernel space is a space which is reserved for our operating systems kernel and its related components. The kernel space is protected from user space. This area is strictly reserved for our operating systems kernel, kernel-extensions and machine hardware. It has full access to all memory and machine hardware. The user can access kernel space only through system calls from our program which is request through kernel services. In simple words, we access kernel space through system calls from kernel-services from user space.WE CANNOT DIRECTLY ACCESS KERNEL SPACE. When need to access kernel space we must go through the system calls. Now lets jump to the User Space 🚀
What is User Space?
User Space is where our program & process’s runs. Each program or application on an unix-like operating system is called a process and each of them has their own unique identifier called Process Identifier (PID).
These spaces can be categorized in few segments. These segments helps organize and manage the memory and user process. Here are common segments in user spaces:
Stack
Stack segment is located right under the kernel space. This provides a clear boundary and helps prevent stack overflows from encroaching from kernels memory.
Mainly this segment is used for function calls, local variables. Each segment calls create a new stack frame functions parameters, return type and local variables. This stack goes upwards/downwards based on the systems architectures.
On most common architecture (like x86), the stack grows downwards in memory. This means we pushed data onto the top of the stack, a stack pointer (a special register that points to the top of the stack) decreases in values, moving towards lower memory address.
Stack is Last-In-First-Out (LIFO) data structure which has only two operations PUSH and POP.
push → adds a new elements to the stack frame
pop → removed the last elements from the stack frame
This segment does all the operations for function calls in a program. Calling functions is same as pushing the function on top of the stack, and once the function completes then it pops and returns from the stack. The stack contains the following data:
arguments passed to the function
return address back to the function
space for local variable in the function
Here’s a following golang program to demonstrate the stack memory allocation
func main() {
res := getResult()
}
func getResult() int {
a := getNum1()
b := getNum2()
return a + b
}
func getNum1() int {
return 10
}
func getNum2() int {
return 20
}
When we call the function it pushes the stack frame on top of the stack. The process execute the stack. After finishing the execution of the function it return and goes out of scope, then the stack frame pops out of the stack. There’s a stack pointer always tracks the top of the stack.
In stack we can only store limited scope data. But it runs very faster then the heap memory.
Stack Overflow
Each program cames with definite size of stack memory. When we have indifinite function calls that are using all the stack memory, there could be situation where there could be no memory available. These will leds us to stack overflow. 💥
Heap
The Heap segment is used to dynamically allocated/dealloacted memory during the program execution. Our Program can request heap memory using function like malloc()
or new
in C. It returns memory address and our program can store data on that address. Also we can remove it from the heap using delete
or free()
to free the memory. Our program can increase/decrease memory from heap as we needed. The heap always grows upwards in memory. The heap has the following characteristics
Memory Allocated or Deallocated in the program execution (runtime).
The heap contains non-contiguous memory address.
Our Program is responsible to release the memory from the heap. These can leads to memory leaks if we forgot the release the memory.
Memory Size is larger and slower then stack.
Btw, Heap is nothing to do with the heap data structure. Unlike, stack which does LIFO to allocates/deallocates memory, heap does it randomly.
OUT OF MEMORY
When there’s no memory left to allocate on heap, then the compiler shows the “Out of Memory” error/warning. This error can vary from programing language. Stack grows downwards and Heap grows upwards.
BSS (Block Started by Symbol)
This segment is used for storing unused Global and Static variables. By default it points to null.
package main
import (
"fmt"
)
var globalVar int
func main() {
fmt.Println("Global variable:", globalVar)
}
Data
This segment is used for storing Global and static variables. These variables has fixed memory location throughout the program execution. The variables could be access/modify throughout the program execution in the data segment. This section is initialize at the compile time.
package main
import (
"fmt"
)
var globalVar int = 10
func main() {
var localVar int = 20
fmt.Println("Global variable:", globalVar)
fmt.Println("Local variable:", localVar)
globalVar = 30
localVar = 40
fmt.Println("Global variable:", globalVar)
fmt.Println("Local variable:", localVar)
}
The globalVar and localVar are stored in the Data segment.
Text
The Text segment is where all the instruction is stored. This is read-only segment which cannot be modify. This prevents accidental modification of the instructions during program execution.
Thank you for your time. I hope this overview of RAM and its relevance to programming has been informative. I welcome any feedback or corrections you may have
Thanks for reading HACKER!