Memory Leak Detection on Windows: Process Explorer and PowerShell

A memory leak does not announce itself. The machine is fine in the morning, sluggish by mid-afternoon, and swapping to disk by evening — and a restart makes it all go away, which is exactly why the problem survives for months. Finding the process responsible takes about ten minutes with tools that are already free.

Leak, or just a large cache?

Not every process with a big memory footprint is leaking. Databases, browsers, and editors deliberately cache in RAM and release under pressure. A leak has a specific signature: memory that climbs steadily, never falls during idle periods, and only resets when the process restarts.

The distinction matters because chasing a well-behaved cache wastes an afternoon. Measure over hours, not minutes.

The three numbers that matter

CounterWhat it measuresWhy it matters for leaks
Working SetPhysical RAM the process currently holdsFalls when Windows trims under pressure — can hide a leak
Private BytesMemory committed to this process alone, not sharedThe honest leak indicator: it does not get trimmed away
HandlesOpen kernel objects (files, registry keys, events)A handle leak looks like a memory leak and is often the real cause

Task Manager shows Working Set by default, which is why it so often says nothing is wrong. Private Bytes is the column to watch.

Process Explorer: the ten-minute method

Process Explorer is a single executable — no installation, no service.

  1. Run it as administrator.
  2. Right-click the column headers, choose Select Columns, and add Private Bytes, Handles, and Working Set.
  3. Sort by Private Bytes descending.
  4. Note the top five processes and their values.
  5. Do nothing for an hour. Look again.

A process whose Private Bytes grew while the machine sat idle is your candidate. Double-click it and open the Performance Graph tab — a leak shows as a staircase that never steps down.

Watching it from PowerShell instead

If you would rather leave a sampler running, Get-Process exposes the same counters:

while ($true) {
  Get-Process |
    Sort-Object -Property PrivateMemorySize64 -Descending |
    Select-Object -First 5 Name, Id,
      @{N='PrivateMB';E={[math]::Round($_.PrivateMemorySize64/1MB,1)}},
      @{N='Handles';E={$_.HandleCount}} |
    Format-Table -AutoSize
  "--- $(Get-Date -Format 'HH:mm:ss') ---"
  Start-Sleep -Seconds 600
}

Leave it in a window for a few hours. The pattern will be obvious in the transcript, and you will have timestamps to correlate against whatever the machine was doing.

When the leak is not in a process at all

If total memory use is high but no single process accounts for it, the leak is likely in kernel memory — a driver holding pool allocations. RAMMap breaks down where physical memory has gone, including paged and nonpaged pool.

Growing Nonpaged pool with no matching process almost always means a driver. Storage, networking, and virtualisation drivers are the usual suspects, and the fix is a driver update rather than anything you can do at the application level.

Handle leaks masquerading as memory leaks

A process that opens files or registry keys without closing them will consume memory indefinitely, and the Private Bytes graph looks identical to a classic leak. The tell is the Handles column climbing in step with memory.

Process Explorer can show exactly what is open: select the process, press Ctrl+H, and watch the lower pane. Thousands of handles to the same path is a conclusive answer, and a far more actionable bug report than "it uses too much RAM".

What to do once you know

You now have a process name and a growth rate. In practice the resolution is one of three things: update the application, disable the offending plug-in or extension, or schedule a restart of that service until a fix ships. None of those require guessing, which is the entire point of measuring first.

If the culprit is a background service you control, a scheduled restart is a legitimate stopgap — just record why it exists, or someone will remove it a year from now and wonder what happened.

Frequently asked questions

Is high memory use bad on its own?

No. Unused RAM is wasted RAM, and Windows deliberately fills it with cache. The problem is growth without release, not a high number.

Does adding RAM fix a leak?

It delays the symptom. A true leak will consume whatever is available; more memory buys hours, not a solution.

Why does Task Manager disagree with Process Explorer?

They default to different counters. Task Manager's "Memory" column is the working set; Process Explorer's Private Bytes counts committed private memory. For leak hunting, trust Private Bytes.

Can I catch a leak that only happens overnight?

Yes — that is what the PowerShell sampler above is for. Redirect its output to a file and read it in the morning.

The short version

Add the Private Bytes and Handles columns, sample over hours rather than minutes, and check RAMMap if no process explains the growth. Ten minutes of setup replaces weeks of daily restarts.

Comments

Popular posts from this blog

10 Essential Windows Keyboard Shortcuts That Will Double Your Productivity

Laptop Touchpad Not Responding? A Step-by-Step Diagnosis

SSD vs HDD: How to Choose the Right Storage for Your Use Case