REW

What Are Loaded DLLs?

Published Aug 29, 2025 4 min read
On this page

A loaded DLL ( Dynamic Link Library) is a file containing reusable code and data that has been mapped into a process's virtual address space by the operating system. This process allows an application to access the functions and resources within the DLL, promoting modularity, code reuse, and efficient memory usage. When a program needs a DLL, it isn't copied into the executable file during compilation but is instead linked and loaded at runtime.

The purpose and advantages of DLLs

DLLs are a fundamental part of the Windows operating system and offer several key advantages:

  • Modularity: They enable a program to be broken down into separate, smaller components. For example, an application might load different feature-specific DLLs only when that functionality is requested, which can lead to faster program startup times.
  • Code reuse: Multiple programs can use the same DLL simultaneously. For instance, the Comdlg32.dll on a Windows system contains code for common dialog boxes, allowing multiple applications to implement an "Open" dialog without each having its own copy of the code.
  • Memory efficiency: The operating system can load a DLL into memory once and share its read-only pages across multiple processes. This reduces the overall memory footprint compared to static libraries, where a copy of the library's code is linked into every executable.
  • Simplified updates: A bug fix or an update to a DLL can be applied by replacing just the DLL file, without needing to recompile or reinstall the entire application.
  • Extensibility: DLLs allow for the creation of plugins and extensions, where new functionality can be added to a program by installing a new DLL.

How DLLs are loaded into a process

The operating system uses two primary methods to load a DLL into a process's memory:

1. Load-time dynamic linking (Implicit linking)

In this method, the application is linked with an import library (.lib file) during compilation. The import library doesn't contain the actual DLL code but rather the information needed by the operating system to find and load the corresponding DLL (.dll file) when the application starts.

  • Process flow: When the program is launched, the operating system's loader examines the executable's header for a list of required DLLs. It then searches for and loads these DLLs into the process's virtual address space before the application begins its main execution.
  • Dependency tree: If a DLL itself has dependencies on other DLLs, the loader resolves these recursively, creating a dependency tree. The entire set of dependent DLLs must be found and loaded for the application to run successfully.

2. Run-time dynamic linking (Explicit linking)

With this method, a program can load and unload DLLs while it is running. This provides more flexibility, as functionality can be loaded on demand.

  • Process flow: The application explicitly calls the LoadLibrary or LoadLibraryEx function to load the DLL into memory.
  • Function access: After the DLL is loaded, the application uses the GetProcAddress function to get the memory address of a specific function within the DLL. It then calls the function using this address.
  • Cleanup: The application can unload the DLL from memory by calling the FreeLibrary function.

Memory management of loaded DLLs

When a DLL is loaded, it is mapped into the virtual address space of the calling process. However, this mapping and memory management are handled in a highly efficient manner:

  • Shared physical memory: Multiple processes can load the same DLL, but the operating system only needs to load the DLL's code pages into physical memory once. These read-only pages are shared among all processes that use the DLL, saving significant physical RAM.
  • Copy-on-write: If a process needs to modify a data page within a shared DLL, the operating system creates a private copy of that page for the process. This "copy-on-write" mechanism ensures that one process's modifications do not affect others.
  • Process-specific context: The DLL code runs within the context of the calling thread and process. This means that the DLL uses the calling process's stack for function calls and allocates memory from that process's heap. Global or static data is typically private to each process, unless explicitly designated as shared memory.

How to inspect loaded DLLs

Developers and system administrators can use various tools to examine which DLLs a process has loaded. This is valuable for debugging, troubleshooting, and security analysis.

  • Windows Resource Monitor: The native Windows tool provides a "Modules" view under the CPU tab, which lists the DLLs loaded by a selected process.
  • Sysinternals Process Explorer: This advanced tool from Microsoft offers a more detailed view. By pressing Ctrl+D, you can see the loaded DLLs for a selected process in the lower pane.
  • Sysinternals ListDLLs: A command-line utility that reports the DLLs loaded by processes. It can list all loaded DLLs or filter for a specific process or DLL.
  • Dependency Walker: A legacy but powerful tool that scans any Windows module and builds a hierarchical tree diagram of all dependent DLLs.
Enjoyed this article? Share it with a friend.