Question:
I am fairly new to powershell programming. I am creating remote sessions to execute some commands programmatically. However its consuming so much memory (in the order of ~150 to 200 MB). ANd more sessions, its more memory.
Can you please help me figure out the issue?
- What is the culprit?
- How can i fix it?
Observations:
1. After executing CreateRunSpace command, its consuming around 3MB.
Someone faced the same issue with creating runspaces:
“Possible PowerShell Runspace Handle Leak”
Still investigating to find the answer though…
Removing pssession made the runspace to release the handles and fixed the memory leak. Its now toggling between ~30 to 40MB.
Thank you!
(FYI – referenced System.Management.Automation.dll)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Management.Automation.Runspaces; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { int success = 0; int fails = 0; for (int i = 0; i < 50; i++) { Runspace rs = RunspaceFactory.CreateRunspace(); //After this the memory will be incremented by ~3Mb in taskmanager rs.Open(); using (Pipeline pl = rs.CreatePipeline()) { Command cmd = new Command("new-pssession"); pl.Commands.Add(cmd); var retval = pl.Invoke(); if (retval.Count > 0) { success++; } else { fails++; } pl.Stop(); } rs.Close(); rs = null; } GC.Collect(); } } } |
Answer:
Looks like removing-pssession from the runspace released the memory handles and fixed the leak. Now its taking ~35MB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
int success = 0; int fails = 0; for (int i = 0; i < 50; i++) { Runspace rs = RunspaceFactory.CreateRunspace(); rs.Open(); using (Pipeline pl = rs.CreatePipeline()) { Command cmd = new Command("new-pssession"); pl.Commands.Add(cmd); var retval = pl.Invoke(); if (retval.Count > 0) { success++; PSSession Session = (PSSession)retval[0].BaseObject; using (Pipeline pl2 = rs.CreatePipeline()) { Command cmd2 = new Command("remove-pssession"); cmd2.Parameters.Add("Id", Session.Id); pl2.Commands.Add(cmd2); var retval2 = pl2.Invoke(); pl2.Stop(); } } else { fails++; } pl.Stop(); } rs.Close(); rs = null; } |