Invisible Race Conditions: The Sometimes Failing Script

DZone 's Guide to

Invisible Race Conditions: The Sometimes Failing Script

Race conditions are a pain and come in many shapes and sizes. In this post, we take a look at a particular one that involves a script that fails only sometimes.

· Performance Zone ·
Free Resource

You probably know that Chrome is a memory hog. I came up with the following extremely brute force manner to deal with it:

Add-Type -TypeDefinition @"

using System;

using System.Diagnostics;

using System.Runtime.InteropServices;

public static class Win32



public static extern bool EmptyWorkingSet(IntPtr hProcess);



foreach($handle in (Get-Process -Name chrome).Handle)


if ([win32]::EmptyWorkingSet($_) -ne $true) {

echo "Failed"



This works quite nicely in 99% of the cases, but sometimes, this fails. Can you see why?

I’ll give you a hint, the EmptyWorkingSet()   returns a failure and an invalid handle error. Why is that?

Well, the problem is a bit tricky. We first execute the Get-Process cmdlet, and extract the handles from the results. That is great, but we don’t keep track of the Process instances that we get from Get-Process, which means that they are garbage.

That means that the GC might clean them, but they require finalization, so at some point, the finalizer will claim them, closing their handles, which means that the EmptyWorkingSet will fail sporadically in a very non obvious way. The “fix”, by the way, is to iterate of the processes directly, not on their handles, because that keeps the process instance live for the duration (and thus its handle).

gc ,memory ,performance ,process ,race conditions ,script

Published at DZone with permission of Oren Eini , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}