summaryrefslogtreecommitdiff
path: root/src/content/blogs/how-computer-memory-actually-works.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/blogs/how-computer-memory-actually-works.md')
-rw-r--r--src/content/blogs/how-computer-memory-actually-works.md198
1 files changed, 0 insertions, 198 deletions
diff --git a/src/content/blogs/how-computer-memory-actually-works.md b/src/content/blogs/how-computer-memory-actually-works.md
deleted file mode 100644
index 42a4acc..0000000
--- a/src/content/blogs/how-computer-memory-actually-works.md
+++ /dev/null
@@ -1,198 +0,0 @@
----
-title: How computer memory ACTUALLY works
-description: Virtual address space, paging, the stack and the heap.
-date: 2025-09-25
----
-
-## How memory is usually taught
-
-Most universities, schools and online courses usually separate memory into 2 places:
-
-- The stack, where all your local variables live.
-- The heap, the magical place where you go get memory if you don't know the size ahead of time.
-
-This is a bit inaccurate, the CPU doesn't really differentiate between the stack and the heap[^1],
-For the CPU, it's all just a bunch of memory.
-
-## Virtual Memory
-
-In the past, programs would use physical addresses to refer to a specific place in the computer's RAM.
-nowadays this is no longer the case, because of several issues:
-
-- Insecure - malicious programs can read or write into another program's memory which may contain passwords or other secrets.
-- Bug prone - a program may accidentally read or write into arbitrary places, causing the entire system to crash
- or misbehave, rather than just the program itself.
-- RAM-limited - the maximum memory limit is how much RAM the computer has, saving and
- restoring memory from disk is not possible.
-
-The way modern CPUs and operating systems solve this problem is by assigning every process (program)
-it's own "virtual address space" and then map virtual addresses into physical addresses.
-
-- Fixes security - each process has it's own address space, and can't access the other address spaces.
-- Fixes bugs - the process is self-contained, crashing doesn't effect other processes.
-- Fixes memory limits - the operating system can intervene and swap memory in and out of disk
- to emulate more RAM (at the cost of lower speeds).
-
-So how does this work?
-
-On 64-bit operating systems, pointers (addresses) are stored as 64-bit numbers, this allows for
-2^64 addreses, which is excessive, in reality, CPUs only use 48 of those bits[^2] to store the address,
-this means the virtual address space is 256TB in size.
-
-```
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| ignored | 48-bit virtual address |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-```
-
-Of course, most computers don't have 256TB of physical memory[^2], for example, I only have 64GB.
-
-The reason this works is **virtual memory may not have physical memory backing it**, and keeping
-track of virtual memory is essentially free[^3].
-You are not storing 256TB of data, you only need to keep track of ranges of virtual addresses and
-their mapping to the physical addresses that back them up.
-
-For performance reasons, the mappings don't store ranges of individual bytes of memory, but rather
-chunks, usually 4k bytes, this is known as a "page".
-
-The operating system sets up a "page table" for each process which maps virtual pages in the process
-virtual address space into physical pages in the computer's RAM.
-
-This is enabled by hardware support. CPUs understand what a "page table" is, and have a special
-register that points to a page table, the operating system then makes sure to set that register
-to the correct page table for the currently running process.
-
-Each entry in the page table has some additional metadata such as:
-
-- Read access bit - whether the process is allowed to read from the page.
-- Write access bit - whether the process is allowed to write to the page.
-- Execute access bit - whether the process can execute code that is inside the page.
-
-We will see why that's useful soon.
-
-## Using Virtual Memory
-
-Operating systems provide through syscalls 4 main operations for dealing with virtual memory:
-
-### Reserve
-
-You ask the operating system to reserve a certain amount of virtual address (must be a multiply of
-the page size), and it gives you back a pointer to the first address.
-
-Reserving only guarantees that if you ask again, it won't give you that same range of addresses,
-but it does not yet ask for physical memory so this operation is essentially free.
-
-Trying to access reserved pages will result in a page fault causing the operating system to
-terminate the proggram with a segmentation fault (segfault).
-
-### Commit
-
-Similar to reserve, but now you are asking the operating system to back up the virtual pages you asked for with physical pages.
-You are allowed to commit pages that you have previously reserved.
-
-The operating system may not back the pages yet with physical pages, but mark the page as "no access",
-as in read, write and execute bits all set to 0.
-
-Trying to access the pages, triggers a page fault, waking up the OS, which checks if the page was commited,
-and if it was, instead of crashing the program, it'd back up the virtual page with a physical page
-(potentially swapping a page from disk), and then resuming the program.
-
-From the program's perspective, everything looks normal except the performance hit due
-to the added delay, which can be measured.
-
-### De-commit
-
-De-commit releases the physical memory backing the page up, and changes the virtual page to being reserved.
-
-### Release
-
-Release releases physical memory of the page AND un-reserves it from the virtual address space.
-
-## What is the stack VS the heap then?
-
-So, if the operating system only deals with pages and virtual memory, then why do people
-differentiate memory into "the stack" and "the heap"?
-
-### The stack
-
-The stack is a region where functions[^4] store their local variables, but it's just
-memory, the compiler specifies the wanted stack size in the executable format (usually 1MB on windows and 8MB on linux),
-and the OS reserves it in the virtual address space when it creates the process.
-
-The heap on the other hand, is a higher-level interface that operating systems usually provide.
-it's a way to allow many big or small allocations, to be as efficient as possible.
-To achieve this, it uses techniques like freelists to chunk many pages into fine-grained allocations.
-
-### Allocators
-
-Things like `malloc` and `free` are examples of heap allocators.
-
-In almost all cases, you don't need such a generic allocator like malloc, and instead, other allocators
-such as arenas and pools cover most use cases.
-
-Arenas are stack allocators, they have a base pointer and a size, and they can push new elements,
-pop the last element, or release the entire thing at once (by resetting to 0).
-
-Use cases for arenas include in games or apps, a frame-arena that you reset at the start of a frame,
-or in web servers a per-request arena that resets when a response is served.
-
-A pool is an arena that stores fixed-size elements, this restriction enables the ability to reuse
-elements that have been freed anywhere, not just the top of the stack like a normal arena.
-
-Use cases for pools are for example in games, a pool for enemies, defeating an enmey and then
-spawning a new one, reuses the space left by the defeated enemy.
-
-For more information on memory management techniques, see [my curated list of resources for managing memory](https://git.kyren.codes/Kyren223/resources#how-to-actually-manage-memory-its-easy).
-
-## A cool trick that virtual memory enables
-
-### Growing a Dynamic array / Vector / List without resizing
-
-The way most languages implement dynamic arrays (like C++, Rust, Go) force a limitation on the programmer:
-pointers are not stable.
-
-This means that if you take a reference to an element in the dynamic array, and then add an element to it,
-the reference may no longer be valid.
-
-This is due to the case where you add an element, if there is not enough space in the array,
-it may need to resize it, by creating a new (larger) array, copying all the elements, and then
-returning the new larger array, so of course retaining a reference to the elements isn't valid.
-
-This annoying restriction can be lifted entirely by using the knowledge we learned about how
-the virtual address space works.
-
-Because the address space is so large (256TB), we can reserve an excessively large chunk, say 64GB
-of it, but only commit a single page, then whenever we need to grow, we just commit more pages.
-
-Of course, 64GB is quite large and takes a decent chunk out of those 256TB, but the point was to
-show it's possible. In practice, you will most likely have some upper bound for how much you are
-expecting to be the maximum, for example in my own codebase, I usually only reserve 64MB.
-
-This works because from the perspective of your program, addresses are contiguous due to using
-virtual memory. The physical pages in RAM that back the virtual memory are basically always
-scattered and fragmented anyways.
-
-## End
-
-As always if you have questions or want to chat, feel free to contact me on discord at Kyren223 or email me at `contact at kyren.codes`.
-
-And if this kind of stuff interests you, I recommend checking out [my curated list of resources](https://git.kyren.codes/Kyren223/resources)
-for further reading about these topics.
-
-[^1]:
- CPUs have 2 registers usually called sp (stack pointer) and bp (base pointer) for
- storing the lower and upper bounds of the currently active stack.
- They are used in instructions like push and pop.
-
-[^2]: Some super computers exceeded the 256TB limit, so certain CPUs support 52-bit or 56-bit addresses
-
-[^3]:
- Misses in the translation lookaside buffer (a cache on the CPU for translating between virtual and physical memory)
- can sometimes become a performance bottleneck (Thanks Martins Mozeiko for pointing this out!).
- This is due to the need of storing an entry for every 4kb page, this can be mitigated by using
- "large pages", which are usually 2MB in size, substantially reducing the amount of needed page entries.
-
-[^4]:
- Procedures is the more correct term, function implies "pure function" with no side effects (like in math),
- while procedures may or may not have side effects.