Most computers today ship with a 64-bit version of Windows, and often a minimal amount of RAM. This brings into question how well these systems perform. This is especially true when users want to run their legacy 32-bit software on these new computers.
A Reader Asks:
Is it true that running 32-bit apps on a 64-bit windows system consumes 1.5 times more memory compared to running the 32-bit app under a 32-bit Windows operating system?
We have previously discussed benefits and drawbacks of keeping everything 64-bit across the board and some of the effects of “mixing and matching”. Today we are going to examine how 32-bit applications execute on 64-bit versions of Windows.
A 64-bit Windows operating system cannot run a 32-bit Windows program without some additional help. They’re just too different: from pointers and data types, to how system calls (how programs use the resources of the underlying operating system). You need some way to make them compatible.
Windows uses the WoW64 (Windows32 on Windows64) subsystem to compensate for the differences. It effectively works as a 32-bit Windows mini-emulator on x64 systems and a full-fledged emulator on Itanium (IA64) systems.
IA64 systems require a full emulator due to the differences in processor instructions and memory page sizes (4K in x86 and x64, 8K in IA64). Since the x64 processors have all the instructions of the x86 processors and uses the same memory page size, it does not have the need for a full emulator.
In both cases, WoW64 provides an interface between the 64-bit Windows kernel and the 32-bit version of ntdll.dll (this contains a list of the core Windows kernel functions), intercepting kernel calls and altering them so they can be processed by the native 64-bit functions provided by the Windows kernel.
There are 3 DLL files used on x64/IA64 systems to achieve this: wow64cpu.dll, wow64win.dll, and wow64.dll. Their functions are to abstract the processor characteristics and provide thunks (we’ll get to them later) into win32k.sys which provides the “window” functionality and ntoskrnl.exe which contains the executive, kernel, memory manager, process scheduler (not to be confused with the Task Scheduler accessible from the Control Panel), and other core elements of the operating system.
A thunk is a subroutine (think of these as a series of instructions that perform a single task) that allows a program to execute a common subroutine or function in the system.
In this case, it extracts the arguments from the 32-bit program’s call stack, converts them to their 64-bit counterparts, and makes the 64-bit system call. Upon return from the call, it will convert the 64-bit results back to 32-bits and push them back onto the program’s call stack for the caller to use.
All thunking is done in user mode (which has limited permissions) for two reasons. First, it minimizes the effects of bugs in the code which could result in a security hole, data corruption, or a system crash if running in kernel-mode.
Second, it reduces the performance impact it would have if running in kernel mode (the mode used by the essential parts of the operating system) due to the overhead involved when switching between user mode and kernel mode and back.
Going back to Itanium systems, there are some other important differences to note. IA64 systems use two additional files. IA32exec.bin is the x86 software emulator and Wowia32x.dll provides the interface between WoW64 and the software emulator.
A 32-bit process will load these files as well as the 64-bit version of ntdll.dll. These are the only 64-bit binaries that may be loaded into a 32-bit process prior to Windows 7. Windows 7 and later also have another DLL, apisetschema.dll, which will be loaded into all processes.
When a 32-bit process is started, it will load Wow64.dll which in turn loads the 32-bit version of ntdll.dll and any necessary 32-bit DLLs from %systemroot%\SysWOW64. Most of these files are identical to the binaries on a 32-bit system although some have been rewritten to behave differently under WOW64.
Looking at the list of DLLs loaded we can see there are 9 DLLs loaded in the process under Win64 that are not there for the Win32 system.
Now, you might be tempted to look at the file sizes, add them up and use that as your basis for how much extra memory is being used, but you would end up with inaccurate results. These files, by their nature, are designed to be shared components and as a result, the first file to require a DLL loads it into memory.
Subsequent programs that require the same DLL do not load the entire component into memory. They get a pointer to the already-loaded component, and allocate RAM for the additional elements which are loaded into the process.
Our Testing Setup
In order to see what is going on, I have set up two virtual machines running Windows 7 Ultimate with 2 GB RAM allocated to each. One of them is the 32-bit version and the other is 64-bit. Both went through the exact same installation and patching process.
After both systems were patched, I disabled the swap file on both to get a better picture of memory usage by ensuring RAM could not be paged out to disk. Once that was complete LibreOffice 22.214.171.124 was installed.
A copy of Sysinternals Process Explorer was also placed on both machines. This is the tool I used to gather memory usage information. The default column setup was changed so I could look at the Working Set and WS Private usage.
These working set numbers reflect the amount of RAM being used by the programs. It it complicated a bit further by reflecting the amount of memory used by shared libraries even if they were already loaded by another process. Because of this, if you add the entire column, it is possible to end up with a total greater than installed RAM. The working set is still the best gauge of exactly how much memory is required for a process.
The processes we are examining are not standing alone either. The various LibreOffice programs launch another process, soffice.exe, which will execute yet another process, soffice.bin. We need to be looking at the totals of all three processes to see the effective memory usage of each program.
For the initial test, I simply opened up Writer, Calc, and Impress individually to look at how much memory they consume without any data being loaded and exported the data from Process Explorer. With Calc and Impress, I had opened a 3.7 MB .xls file and 3.9 MB .pptx file respectively and recorded the new memory usage. The results can be seen in the table below. All data is in KB.
The big surprise occurred with Impress. Without a document it was using 4.1% more RAM on the 64-bit system and 9.9% less with the document loaded. I dug up a few other presentations and had similar results with all of them. The 64-bit system ended up using less RAM than the 32-bit system.
So, do the 64-bit versions of Windows require more RAM than their 32-bit counterparts when running 32-bit apps? In general, yes.
But do you need to upgrade your RAM? Probably not. The difference really isn’t that massive. It’s certainly not 1.5 times different.