Fundamentals 12 min read

Why 640K Was Once “Enough” and How Modern Memory Management Solves It

From Bill Gates’s 640 KB claim to today’s multi‑gigabyte machines, this article explains how loaders map executable files, the evolution from segmentation to swapping and paging, and why virtual memory lets programs run with far less physical RAM despite performance trade‑offs.

JavaEdge
JavaEdge
JavaEdge
Why 640K Was Once “Enough” and How Modern Memory Management Solves It

Program Loading Challenges

When an executable file (ELF on Linux, PE on Windows) is started, the loader parses the file format, allocates memory for code, data, and stack, and copies the required sections into RAM. The loader must satisfy two constraints:

The program’s address space must appear contiguous to the CPU.

Multiple programs must be loadable simultaneously without each program hard‑coding a physical address.

Operating systems therefore create a virtual address space for each process and maintain a page‑table‑like mapping that translates virtual addresses to actual physical memory addresses . The process only sees virtual addresses; the kernel resolves them to physical frames.

Memory Segmentation

Early systems satisfied the above constraints by allocating a single contiguous block of physical memory and mapping it to a contiguous range of virtual addresses. This technique is called segmentation . Each segment is a continuous region that the program can address.

Segmentation eliminates the need for a program to know physical locations, but it suffers from external fragmentation. For example, on a machine with 1 GB RAM:

Load a graphics program → 512 MB.

Load a browser → 128 MB.

Load a Python script → 256 MB.

If the browser terminates, the free space is split into two 128 MB holes surrounding the 512 MB and 256 MB allocations. A new 200 MB program cannot be placed because no single contiguous region of that size exists, even though the total free memory (256 MB) is sufficient.

Segmentation fragmentation example
Segmentation fragmentation example

Memory Swapping

To reclaim a contiguous region, the OS can write the contents of a whole segment (e.g., the 256 MB Python segment) to a swap area on disk, free the physical frames, and then reload the data into a new contiguous location adjacent to the 512 MB segment. The swapped‑out pages are later read back on demand. Swapping solves fragmentation but introduces a performance penalty because disk I/O is orders of magnitude slower than RAM access.

Memory Paging

Paging refines the idea of swapping by dividing both virtual and physical memory into fixed‑size blocks called pages . On most Linux systems the default page size is 4 KB.

Linux page size
Linux page size

Because memory is pre‑partitioned into equal pages, external fragmentation disappears; the free memory consists of a set of unused pages. When memory pressure occurs, the kernel can swap out only the pages that are not actively used, dramatically reducing pause time compared with whole‑segment swapping.

Paging diagram
Paging diagram

Page Fault Handling

If a process accesses a virtual page that is not resident in RAM, the CPU raises a page fault . The kernel then:

Locates a free physical frame.

Reads the required page from the swap area (or from the executable file) into that frame.

Updates the process’s page table to map the virtual page to the newly loaded frame.

Resumes the faulting instruction.

This mechanism allows programs larger than the total physical RAM to run, because only the pages actually needed at a given moment occupy RAM.

Practical Observations

Modern operating systems combine virtual memory, segmentation (mostly for legacy compatibility), swapping, and paging to present each process with a large, contiguous address space while using only a fraction of physical RAM at any instant. Typical workloads only keep a few active pages in memory; the rest remain on disk.

Because disk access latency is much higher than RAM latency, having several gigabytes of RAM is still essential for good performance. Nevertheless, the page‑fault mechanism ensures that even very large applications can execute on modest hardware.

How to Inspect Page Size on Linux

Run any of the following commands: getconf PAGESIZE or sysconf(_SC_PAGESIZE) # from a C program Both return the system’s page size in bytes (commonly 4096).

Reflection on JVM Loading

When a Java program runs, the Java Virtual Machine (JVM) itself is a native executable that is loaded using the same virtual‑memory mechanisms described above. Inside the JVM, object allocation and class loading are performed within the JVM’s own heap, which is just another region of the process’s virtual address space. The underlying OS still handles paging and swapping for the JVM’s memory pages.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Memory ManagementOperating SystemsVirtual MemoryPagingSegmentation
JavaEdge
Written by

JavaEdge

First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.