SharePoint+PowerShell Leak Workarounds

Zach Rosenfield recently posted about an obscure memory leak issue when working with PowerShell and the SharePoint object model. You can read his post for details but in summary:

  1. PowerShell spawns a new thread for each pipeline (essentially any batch of code that runs together).
  2. SharePoint objects should not be used across multiple threads due to mechanics of the unmanaged heap.
  3. SharePoint objects used across multiple pipelines result in unmanaged heap leaks until PowerShell closes or you run out of memory.

This PowerShell behavior is easy enough to verify:

PS 1> function Get-ThreadId { [Threading.Thread]::CurrentThread.ManagedThreadId }
PS 2> set-alias gt Get-ThreadId
PS 3> gt
6
PS 4> gt
4

So we need to ensure that our SharePoint objects are allocated, used and disposed within the same thread. How can we do this? Zach offers two suggestions, but there are actually several options:

Single Line

PS 5> gt; gt; gt
10
10
10
PS 6> gt; `
>> gt; `
>> gt
>>
3
3
3

Script

PS 7> @"
>> gt
>> gt
>> "@ > gt.ps1
>>
PS 8> .\gt.ps1
8
8

Function

PS 9> function gt2 {
>> gt
>> gt
>> }
>>
PS 10> gt2
4
4

Inline Script Block

PS 11> &{
>> gt
>> gt
>> }
>>
7
7

My Using Function

PS 12> using Microsoft.SharePoint
PS 13> gt; using ($s = [Microsoft.SharePoint.SPSite] 'http://moss') {
>> gt
>> $s.Url
>> gt
>> }
>>
5
5
http://moss
5

Cmdlet + Wrapper Class

Gary Lapointe has a set of PowerShell cmdlets that use wrapper objects to hide SPSite/SPWeb objects unless you specifically ask for them.

PS 14> $spi = Get-SPSite-gl 'http://moss'
PS 15> gt; using ($s = $spi.SPBase) { $s.Url; gt }
8
http://moss
8

The severity of this issue depends on your environment and the kinds of scripts you’re running, but in memory-sensitive and production environments these are definitely some techniques to keep in mind.

Advertisement

4 Responses to “SharePoint+PowerShell Leak Workarounds”

  1. SharePoint Link Love 21-Feb-2009 - wss.made4the.net: by Jeremy Thake Says:

    […] SharePoint+PowerShell Leak Workarounds « Solutionizing .NET […]

  2. Stephen Mills Says:

    Why not just use “Powershell -STA”? That way it always uses the same thread. WPF and many Com objects require using Powershell this way. I actually haven’t found a compelling reason to use the default MTA mode in Powershell. I’ve found too many little issues with different classes/objects that require the same thread be used throughout the lifetime of the object.

    -Stephen

  3. SharePoint 2010, PowerShell and thread-safety | Anders on SharePoint Says:

    […] Also code called within the same cmd-let/Function and Inline script-blocks are executed in the same thread (see more details on this subject on Keith Dalbys pre-SP2010 blog post here). […]


Comments are closed.

%d bloggers like this: