Video summary
Investigating the Dragon Age Memory Leak
Main summary
Key takeaways
Overview
Josh Strife and Nathan Bags discuss a long-running performance/crash issue in Dragon Age (Origins) that many players incorrectly attribute to an “unfixable memory leak.” The core finding is that the game’s behavior is driven by 32-bit memory address limits, heap fragmentation, and texture allocation failures.
While the community has a workaround, fully “fixing” the underlying engine behavior would require much deeper changes than simple patching.
Key issue: loading screens get longer, then crashes
- Symptom: As playtime increases, area transitions (inside ↔ outside, overworld travel, etc.) become slower because the loading screen length increases dramatically.
- Common claim: Players often describe it as a memory leak where memory is never reclaimed, requiring a restart.
- Investigator framing: The problem is not a leak in the literal sense, but rather poor optimization / allocator behavior that eventually leads to instability.
Practical workaround: LAA (Large Address Aware) / 2GB → 4GB
A widely known workaround is enabling LAA (“Large Address Aware”) for the game executable.
- Explanation:
- Dragon Age is a 32-bit process, which on 32-bit Windows typically limits it to 2GB of address space.
- On 64-bit Windows, enabling LAA allows the process to use up to 4GB of address space, delaying the failure mode.
- Important distinction:
- If it were a true leak consuming memory indefinitely, LAA would only delay the inevitable.
- Instead, it stabilizes the specific failure condition, suggesting the main bottleneck is address space pressure rather than endlessly unreleased allocations.
Why it crashes: fragmentation and “largest contiguous free block” drops
Using reverse engineering + runtime instrumentation, the investigation argues that the decisive metric is virtual address space fragmentation, not merely “used memory.”
They track:
- Total virtual memory remaining (not just used memory)
- Largest contiguous free region (the biggest single block of free space)
Key conclusion:
- The game’s heap becomes “Swiss cheese” (many small gaps).
- Even if there’s still total free address space, there may not be a large enough contiguous block to allocate big resources—especially textures.
- Crashes become more likely as the largest free contiguous block shrinks to only a few MB.
Instrumentation method: hooking DirectX9 via a proxy DLL
To observe what the engine is doing, Nathan describes custom tooling.
- Because Dragon Age uses DirectX 9, it loads
d3d9.dll. - They exploit Windows’ DLL search behavior:
- Windows checks the game directory first, then system folders.
- By placing a crafted
d3d9.dllin the game folder, code can run before the real system DLL (a proxy / man-in-the-middle).
- With hooking in place, they can:
- render overlays
- intercept DirectX calls
Rendering overlay + in-game metrics (debug UI)
They inject an on-screen overlay (using ImGui) that displays:
- process memory usage graphs
- counts of live DirectX resources (e.g., textures, vertex buffers)
This supports the idea that:
- textures/resources often increase then fluctuate (suggesting streaming/invalidation)
- however, fragmentation/allocator state still trends toward eventual failure under long sessions
Texture allocation failure mechanism (and why it feels “unfixable”)
The deeper technical finding is that when the game cannot allocate textures (eventually an out-of-memory-related error), the engine enters an unstable “undefined behavior” state.
Observed symptoms:
- Flickering / cycling textures on models (including odd defaults)
- visual glitches in effects/blending
Why it’s hard to truly fix:
- Correct handling requires tracing the full lifetime of textures after creation and understanding how the engine proceeds when allocations fail.
- The implied proper fix would require major changes across the engine’s allocator/resource pipeline—potentially including low-level patching at the assembly level.
- Replacing or rewriting the allocator is described as extremely risky and extensive.
Clarification added mid-investigation: error handling exists, but leads to bad state
A correction is added during narration:
- The engine does handle the
CreateTextureerror. - However, it handles the failure in a way that still results in flickering/undefined rendering rather than graceful recovery.
So the issue isn’t simply “it ignores the return value,” but rather: it handles the failure incorrectly, producing an inconsistent state.
Developer console / debug concepts mentioned
They note that debug overlays/menus may sometimes remain accessible in builds (or via debug UI). This is used as an example of how hacking tools can reveal instrumentation paths—though it’s mostly background for how the overlay approach works.
Guidance / analysis takeaway
- The “fix” players use (LAA / increased address space) is framed as a brute-force workaround that avoids the worst-case contiguous allocation failure.
- Fully resolving the engine-side allocator/texture failure behavior is described as not practical through simple patches without heavy reverse engineering and potential rewriting.
Main speakers / sources
- Josh Strife (YouTube/Twitch): MMO/RPG reviewer; series “Worst MMO Ever”; hosted/created the Dragon Age content that motivated the investigation.
- Nathan Bags (YouTube/Twitch): reverse engineering / low-level programming; focuses on debugging, DRM/game preservation, and custom tooling.