How Windows 98 Handled Memory Fragmentation

Microsoft Windows 98 struggled significantly with memory fragmentation during extended uptime sessions, primarily because its hybrid 16-bit/32-bit architecture lacked modern low-fragmentation memory managers. While the operating system utilized a 32-bit Virtual Memory Manager to handle physical RAM through 4 KB paging, its reliance on legacy fixed-size resource heaps, poorly isolated virtual address spaces, and non-compacting memory allocators meant that extended sessions inevitably led to severe fragmentation, memory leaks, and system instability.

The Virtual Memory Manager and Paging

Windows 98 handled core physical memory using the Virtual Memory Manager (VMM32). The VMM implemented standard demand-paged virtual memory, dividing physical RAM into uniform 4 KB pages. At the physical hardware level, paging inherently prevented physical memory fragmentation from blocking allocations, as the operating system could map non-contiguous physical pages into a contiguous virtual address space.

However, this abstraction only resolved physical RAM fragmentation. Within the 4 GB virtual address space shared across the operating system and running processes, contiguous free memory ranges frequently degraded over time.

Virtual Address Space Fragmentation

In Windows 98, all running applications shared the upper half of the 4 GB virtual address space (between 2 GB and 4 GB), which housed shared system components, virtual device drivers (VxDs), and dynamically loaded DLLs.

Because many 32-bit dynamic link libraries (DLLs) and memory-mapped files had fixed base memory addresses, loading and unloading applications during long uptime sessions caused "swiss cheese" fragmentation within this shared arena. When programs requested large contiguous blocks of virtual memory via VirtualAlloc, the requests frequently failed—not because the system lacked free memory, but because no single contiguous block of virtual addresses remained large enough to satisfy the request.

Legacy 16-Bit GDI and User Heaps

The most severe bottleneck in Windows 98 came from legacy compatibility structures: the GDI (Graphics Device Interface) and USER heaps. To maintain compatibility with Windows 3.1 software, Windows 98 retained several 16-bit heaps that were strictly capped at 64 KB each.

Every window handle, font, menu, icon, and graphical brush allocated by any software was tracked within these tiny heaps:

  • No Dynamic Compaction: The heap manager could not effectively relocate existing allocations to compact the remaining space without breaking active pointers held by legacy 16-bit applications.
  • Resource Depletion: As programs continuously created, modified, and closed graphical elements over long sessions, these 64 KB segments became severely fragmented.
  • False "Out of Memory" Errors: Once a heap ran out of contiguous room for new handles, the system reported an "Out of Memory" error and locked up, even if the computer still had hundreds of megabytes of free physical RAM.

The Dynamic Swap File (WIN386.SWP)

To counter memory starvation, Windows 98 used a dynamic swap file (WIN386.SWP) that expanded and contracted based on system demand. During extended uptimes, when physical RAM fragmented and memory leaks consumed available pages, the VMM aggressively offloaded inactive pages to the hard disk.

While this dynamic expansion prevented instant crashes, it caused intense disk thrashing. Additionally, it transferred the fragmentation problem to the FAT32 file system, where the swap file itself became physically fragmented across the disk platter, further degrading system performance over time.

Lack of Native Low-Fragmentation Heaps

Unlike modern Windows NT-based kernels (such as Windows 2000 and XP), Windows 98 lacked a Low-Fragmentation Heap (LFH) mechanism. Standard Win32 heap management relied on basic best-fit or first-fit algorithms without native sub-segmentation designed to prevent small allocations from breaking up larger blocks.

Over long sessions, frequent memory allocation and deallocation left the heap filled with unusable, microscopic gaps. Third-party software utilities, commonly branded as "RAM boosters" or "memory defragmenters," tried to resolve this by forcing the system to page out entire applications to disk, but these tools merely cleared physical RAM temporarily without solving the underlying virtual heap fragmentation.

The Inevitability of the Reboot

Windows 98 included no automated background garbage collection or address space defragmentation routines. Once the shared address space or 16-bit system heaps fragmented, the degradation was permanent for the remainder of that session. Consequently, long uptime was practically unattainable; regular reboots remained the only effective method to reset the heaps and fully restore system stability.