We are having issues with the IIS cmdlets being used in WinRS, requiring an increased value of the MaxMemoryPerShellMB setting.
We get a bunch of random errors each time we hit the limit and we identified the problem by monitoring the memory of the wsmprovhost processes.
Since we are creating many things in one wsmprovhost process (sites, applications and application pools) I do not know what all the calls are that are leaving allocated memory behind. The following example of getting an application pool is just one of them.
Using:
Get-WebConfigurationProperty -filter "//site[@name='Default Web Site']/application" -Name applicationPool | select value -Unique
...will not cause the shell's allocated memory to increase so much. It also seems it decreases after a while and even when you force a GC.Collect.
However, with a small addition to the command above, this will leave allocated memory behind:
Get-WebConfigurationProperty -filter "//site[@name='Default Web Site']/application" -Name applicationPool | select value -Unique | %{ get-item (join-path "IIS:\AppPools" $_.value) }
To verify this behavior:
1. Set up two PSSessions to the target host with IIS installed
2. Monitor the wsmprovhost processes in one of the sessions by issuing the folllowing command:
while(1) { Get-Process wsmprovhost; sleep 5 }
3. In the other session, call the memory leaking command in a loop:
1..1000 | %{ Get-WebConfigurationProperty -filter "//site[@name='Default Web Site']/application" -Name applicationPool | select value -Unique | %{ get-item (join-path "IIS:\AppPools" $_.value) } }
4. You will now see the memory load increasing of one of the shells - something like this:
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 303 26 59900 66636 583 0,42 4644 wsmprovhost 301 25 59900 66656 583 0,42 4644 wsmprovhost 342 27 62164 73400 584 0,69 4644 wsmprovhost 342 27 62164 73400 584 0,69 4644 wsmprovhost 342 27 62164 73400 584 0,69 4644 wsmprovhost 342 27 62164 73400 584 0,69 4644 wsmprovhost 342 27 62164 73400 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 339 27 62080 73384 584 0,69 4644 wsmprovhost 384 32 66620 82612 603 1,20 4644 wsmprovhost 459 33 117036 131920 616 4,56 4644 wsmprovhost 405 33 130692 145848 616 8,19 4644 wsmprovhost 395 33 184864 200212 616 11,79 4644 wsmprovhost 386 33 260608 271436 751 15,40 4644 wsmprovhost 389 32 336288 348812 757 19,34 4644 wsmprovhost 382 32 421332 433764 898 23,26 4644 wsmprovhost 382 32 526912 529696 1040 27,14 4644 wsmprovhost 379 32 623264 626392 1040 31,34 4644 wsmprovhost 395 34 669152 672440 1170 33,31 4644 wsmprovhost 405 34 669160 672488 1170 33,32 4644 wsmprovhost 405 34 669160 672488 1170 33,32 4644 wsmprovhost 407 34 669160 672504 1170 33,32 4644 wsmprovhost
I was able to get a local (not using WinRS) powershell instance eat 1600 MB of RAM using the loop above.
We have used our script since Server 2003 and PowerShell v1 and never had any issues with this. When we upgraded to Server 2008 R2 we needed to increase the MaxMemoryPerShellMB setting from 150 to 512.
Yesterday we pushed out a release which included one more application and application pool and we hit the limit again. We was able to work around this problem by increasing the setting up to 1024 MB.
As you can see it was quite easy for me to push it over a 512 MB limit just by using Get-Item on an application pool.
Why is the Get-Item command causing this? Should I avoid it and use, where possible, Get-WebConfigurationXX cmdlets instead?
Thanks in advance for your assistance!
Best regards,
Johan Andersson
https://github.com/anderssonjohan