Skip to main content
Loading Explore guides…
Virtual Memory · Acedra
Home
Explore
Computer Science
Virtual Memory
Sign in to save
Chat
If YouTube asks you to sign in, open the video on YouTube.
Watch on YouTube
Reload player
Transcript
40 segments
Copy
Hide video
0:00
Have you ever thought about how weird is that we can just keep opening the apps like you got a browser with 50 tabs open, a code editor and maybe a game in the background and your laptop just handles it. It feels like you have an infinite memory but in reality you probably just have one or two physical sticks of RAM with a strict hardware limit. If you add up what all those apps actually want they shouldn't fit. So how are all there running at the same time without crashing into each other?
0:28
How does the OS take a fixed amount of hardware and make it feel completely limitless? What's actually happening under the hood is one of the most elegant design patterns in the computer science. It's a layer of abstraction that changes how software interacts with the hardware entirely. To understand how we got here, we have to look at the brute force era and why simply handling programs raw chunks of physical memory failed almost immediately. We will look at the evolution
0:57
of the virtual memory moving from early days of base and bound registers to how modern paging works under the hood. We are also going to look at what happens when your RAM actually fills up and how OS decide what to keep and what to kick out. And why your system completely grants to a halt where it's pushed to the edge by the end of this video, you won't just know how memory works. You will understand exactly how the operating system maintains this illusion, just so that your code can run.
1:29
To understand how we got here, we have to look back at the time when the memory was brutally unforgivingly finite. In the early days of computing there was no abstraction. This was the era of physical addressing. When the programmer wrote a line of code to store a number, they weren't asking the operating system for a favor. They were talking directly to the hardware. If the code said store this at the address 500, the CPU literally send a voltage signal down to
1:57
a physical pin number 500 on the memory chip. It was direct, it was fast and it was a total disaster because the problem was simple, ownership If you wanted to run two programs at the same time, they both had to live in the exact same RAM. But because both programs were written, assuming they had the whole machine, they would inevitably collide. Program A would write a value to the memory cell and millisecond later a program B could overwrite it. There was no protection, there were no walls.
2:30
In this lawless era, a single bug in the calculator app could reach across the physical silicon and corrupt the memory of the entire operating system. One mistake didn't just crash your app, it killed the whole machine. Even if you were lucky enough to avoid a crash, you were haunted by a ghost called external fragmentation. Let's look at the map to see how this actually trapped the system. Imagine you have 64 kilobytes of RAM, you load three programs side by side.
2:57
Program A, B and C takes up 20 kilobytes. That leaves you with tiny 4 kilobytes chunk at the very end. Your RAM is almost full. But then you close the program B, the one sitting right in the middle. Suddenly that middle 20 kilobytes opens up, it becomes a hole. If you calculate your total free space right now, you have 20 kilobytes hole in the middle plus the 4 kilobytes chunk at the end, that is 24 kilobytes of total free memory. Now you try to load a 22 kilobytes program
3:34
on the paper, 22 fits into 24, but the system rejects it. Why? Because your largest single gap is only 20 kilobytes wide. And back then a program couldn't be split up It required one single unbroken chain of memory, what we call a contiguous block. The memory was physically right there on the hardware, but because it was scattered, it was completely useless. Computer scientists realized that as long as software could see hardware, we would always be trapped by this physical boundaries.
4:06
To break free, they had to do something radical. They had to stop letting programs see the truth. We needed to create an illusion. A world where every single program thinks it has entire computer to itself. A world where every program starts right at the address 0 and sees a vast empty playground. Even if in reality it is being squeezed into tiny corner of crowded ram. This was the birth of virtual address space, but the first attempt
4:33
to build this translation layer, a hardware system known as base and bounds was a pretty clumsy rigid solution. And it was about to show us how difficult lying to the software actually is. In the late 1960s, hardware engineers introduced a specialized piece of circuitry inside the CPU called the memory management unit or the MMU. The MMU was designed to perform a simple high-speed magic trick. Imagine the operating system loads a program into the RAM, starting at the physical address 30,000.
5:07
The program is not told this, instead the operating system stores the value 30,000 inside a special hardware register called base register. Now the CPU starts running the program. From the programmers point of view, it thinks its own memory starting at address 0. So, when the program sees read data from address 0, the request first pass through the MMU. The MMU instantly adds a base value 30,000 to it and converts it into a real physical address.
5:36
That translated address is actually what gets sent to the RAM. If the program later tries to access address 200, MMU adds 200 to 30,000 to become 30,200. This translation happens automatically for every memory access. To the program, it looks like it's operating at the very beginning of the memory, but in reality every address is being shifted to a safe isolated region of physical RAM chosen by the operating system. But relocation was only half the battle. We also needed protection.
6:14
So, engineers added a second piece of hardware alongside the base register called the bound register. When the operating system loaded a program into the memory, it now stored two numbers inside the CPU. The first one was the base register, the physical starting address of the program. The second one was the bound register, the total amount of memory the program was allowed to use. For example, the OS might load a program at physical address 30,000 and give it 1000 bytes of memory.
6:42
So, the hardware register would contain base equal to 30,000 and bound equal to 1000. Now, the CPU starts executing the program. To the program itself, nothing has changed. It still believes its own memory starting at address 0. When it tries to access address 200, the MMU performs two operations in hardware so fast that the program never notices. First, it checks is 200 smaller than 1000. Yes, that means the access is legal.
7:18
So, the MMU adds a base address 30,000 to the virtual address that is 200 to get the physical address 30,200. And this real physical address is sent to RAM. But now, imagine the program tries to access address 1500. Again, the MMU performs the same check, is 1500 smaller than 1000. No, at that exact moment the hardware knows the program is attempting to reach outside its assigned memory region. Maybe it's a simple programming bug,
7:49
maybe it's a corrupted code, or maybe it's trying to steal data from another program. It doesn't matter. The CPU immediately blocks the access and raises a hardware exception, a segmentation fault. Execution stops is strongly and control is handed back to the operating system, which usually kills the offending program on the spot. This actually changes the computing forever. For the first time in the history, memory protection was enforced directly by the hardware.
8:18
A single broken application could no longer corrupt the entire machine or crash every other running program with it. It was brilliant start, but there was a massive problem that would eventually make this system completely unusable for the modern computing. Base and bounds still required every single program to be stored as one single unbroken chunk of memory. Imagine you have program that needs 10 megabytes of space. You look at your program and you technically have 15
8:48
megabytes of total free memory, but it's split into two separate gaps of 7 and half megabytes each. Even though you have more than enough total memory to run the app, the base and bound system is completely stuck. It has nowhere to put a single continuous 10 megabyte block. To fix this, operating system had to perform a process called compaction. OS will literally stop everything. Pick up all the programs currently running in RAM and shift them together to close the gaps.
9:20
It was like trying to reorganize a bookshelf while people are actively trying to read the books. It was incredibly slow. It wasted massive amounts of CPU power and programs got larger. Those pauses became frustratingly noticeable to the user. We had solved the problem of protection, but we were still slaves to the physical layout of the RAM. If we wanted to truly make memory feel infinite, we had to stop thinking in giant rigid chunks. We had to break the programs apart.
9:53
Think about how a program actually lives in memory. It's not just one big pile of data. You have the code, the actual instructions that never change. You have the heap where you are to variables and data structure grow and shrink and you have the stack which constantly tracks your active function calls in the old system because everything was jammed into one rigid block. If your heap grew too large, it could crash right into your code or just run out of room completely.
10:20
Even if there was plenty of empty space sitting elsewhere in the RAM. To solve this, engineers evolved the base and bound idea into a system called segmentation. Instead of giving program, just one base and bound, the hardware gave it several. Suddenly, a program wasn't forced to be one giant block anymore. It became collection of independent segments. The code got its own segment, the heap got its own, the stack got its own. Each of these segments
10:50
had its own dedicated entry in the segment table. These finally allowed the OS to be much better about where it put things. It could drop the code into one part of RAM and scatter the heap into completely different area. Basically, wherever it could find that fit. But the real genius of the segmentation wasn't just about fitting into gaps. It was about permissions. Because the code segment was now completely separate, the hardware could make it read only.
11:21
This meant that even if a program had a massive bug, it physically could not override its own instruction. Even better, if you were running 10 instances of the same text editor, the OS only had to keep the single copy of the code segment in the physical RAM. All 10 programs could safely point to the exact same physical memory for their instructions while maintaining their own private segments for their unique data. Segmentation was massively forward. It gave us isolation shared memory
11:54
and a logical organization. But it didn't kill the ghost we met earlier, the external fragmentation problem. Because segments were still variable in size, somewhere small, somewhere massive, we were still playing a game of Tetris with our RAM. As segments were created and destroyed, the physical memory once again become a Swiss cheese of tiny unusable holes. The operating system was still spending too much time moving these massive segments around just to try and make a room.
12:24
The industry finally realized that the problem wasn't how we divided the program. The problem was that we were still trying to fit variable size things into fixed size hardware reality. To finally solve this, we had to stop letting the program, dictate the size of blocks. We had to chop everything into identical bite sized pieces we had to move to paging. So, now engineers decided to chop up all the physical RAM into small identical fixed size slots called page frames.
13:00
In modern systems, these are almost always exactly 4 kilobytes in size. At the same time, we do exact same thing to the program. We chop programs virtual address space into identical pieces called pages. And this is where magic happens. In a paging system, a program doesn't need a continuous block of physical RAM anymore. Because every single program of the RAM is exactly same size as every frame in the memory. Any page can go anywhere.
13:30
Page 1 of your browser could be at the very beginning of your RAM stick. Page 2 could be at the very end. Page 3 could be right in the middle. To the program, it still looks like a single unbroken line of memory. It has absolutely no idea. It is being scattered across the silicon like a jigsaw puzzle but of course, if you are going to scatter program all over the RAM, you need a reliable way to find the pieces. This is the job of the page table. Think of page table as the master map
14:00
managed by the operating system. Every single time, the CPU wants to read a virtual address, it checks this table to find the physical translation. It is basically saying virtual page 5. Let me look at the map. That is currently sitting in physical frame 92. This completely killed external fragmentation forever. Because every single hole in your RAM is now exactly the size of the page. There is no such thing as a gap that is too small. If you have a free frame, you can use it period.
14:30
But as any engineer will tell you, there is no such thing as a free lunch. By moving to paging, we traded external fragmentation for two new problem. First, we created internal fragmentation. If a program only needs single byte of data, the system still has to allocate a full four kilobyte page. If you have thousands of tiny data allocations that empty wasted space starts to add up. Second and much more importantly, we introduced a massive latency penalty.
15:01
Now, every time CPU wants to read a single piece of data, it has to look at the RAM twice. One to check the page table to find out where the data actually lives and second time to go back and get the data itself. In the world of high performance computing, doubling your memory access time is absolute death sentence. To make this system fast enough to actually be usable, we needed one final piece of hardware called the TLB. Think of TLB as a fast address cache.
15:33
It simply stores the most recent translation the CPU has made. Now when the program asks for a memory address, the CPU first checks this tiny lightning fast buffer. If the translation is already in there, what we call a TLB hit, the address is translated instantly with the zero extra trips to RAM. It's only when we have a TLB miss, the system has to go long way around and do a slow page table walk to find the address. But thanks to the ways we naturally access memory in the
16:04
clusters, we actually hit the TLB over 99% of the time. The little piece of silicon is the entire reason the virtual memory is fast enough to be practical. But there is still one big question left. How does the system make memory feel truly unlimited? What happens when you actually run out of physical RAM? What happens when you open that 51st browser tab and the RAM is physically full? This is where operating system performs its final most daring trick. It's time to talk about page fault.
16:40
Up until now, we have assumed that every single virtual page a program uses eventually finds a home inside the physical RAM. But in a modern world, full of heavy multitasking that is often completely impossible. You might have only 16GB of RAM on your motherboard. But your open applications are collectively demanding 30 GB of space. This is where operating system reveals the final layer of illusion, a strategy called demand paging. When you run
17:07
on the program, the OS doesn't actually load your entire program into the RAM. It's way lazier than that. Instead, it loads only the bare minimum needed to start up. And marks the rest of the pages in the page table with a special flag called not present. The moment your program tries to access one of the not present pages, the CPU hits a wall. It triggers a hardware exception called a page fault. To the program, it looks like a crash is about to happen.
17:37
But behind the scenes, the operating system springs into action. It completely pauses the program, rushes over to your SSD or hard drive, finds the missing page and copies it into free slot into the RAM. Once the data is safely in place, the OS updates the page table, flips that flag to the present flag and tells the CPU, okay, try again. The program resumes having absolutely no idea it was ever paused. It was actually sitting on the storage drive away from the RAM.
18:13
To the software, it just feels like the memory was always there. But what happens when the RAM is 100% full? To bring the new page in from the disk, the OS has to kick an old page out. This is where we run into replacement policy. The operating system has to look at all the data currently running in the RAM and find the pages that haven't been touched in the long time, often using an algorithm called LRU or least recently used
18:46
The OS takes that cold data, a evicts it by writing it back to the disk and hands the newly empty RAM frame to the active program. However, this magic trick has a brutal breaking point. If you open too many demanding apps all at once, the operating system can get caught in a terrifying death spiral known as thrashing. This happens where your system is so desperately low on RAM that it's constantly kicking out pages that it needs again just a fraction of millisecond later.
19:18
The CPU ends up spending 1% of its time actually running your code and 99% of its time just frantically moving data back and forth between the RAM and the disk This is the exact moment your computer suddenly slows to a painful crawl the cursor's stutters across the screen and your hard drive activity light goes completely solid. So, here the illusion starts finally shattering against the hard reality of the physics. So, we have seen that how a computer takes a physical
19:52
limited piece of RAM and makes it feel truly unlimited. It does it through a masterpiece of cooperation between hardware and software. We saw concepts like physical addressing, segmentation, paging, TLBs and problem called thrashing. So, next time you open dozen tabs and your laptop doesn't complain take a second to appreciate the silent invisible war being fought right under your keyboard. If you were to unmask more of the foundational magic tricks hidden inside your
20:26
machine from how CPUs predict the future to how operating system manage thousand threads at once hit that subscribe button and let me know what we should dive into next down in the comments. Thanks for watching.
Here to help you learn
Sign in to keep a private conversation with your course tutor.
Ask me anything about the material…
Sign in to chat