{"action":"created","issue":{"url":"https://api.github.com/repos/PowerShell/PowerShell/issues/5746","repository_url":"https://api.github.com/repos/PowerShell/PowerShell","labels_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/5746/labels{/name}","comments_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/5746/comments","events_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/5746/events","html_url":"https://github.com/PowerShell/PowerShell/issues/5746","id":284592899,"number":5746,"title":"Runspace pool memory leaks (v6, v5, no leaks in v2)","user":{"login":"nightroman","id":927533,"avatar_url":"https://avatars3.githubusercontent.com/u/927533?v=4","gravatar_id":"","url":"https://api.github.com/users/nightroman","html_url":"https://github.com/nightroman","followers_url":"https://api.github.com/users/nightroman/followers","following_url":"https://api.github.com/users/nightroman/following{/other_user}","gists_url":"https://api.github.com/users/nightroman/gists{/gist_id}","starred_url":"https://api.github.com/users/nightroman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nightroman/subscriptions","organizations_url":"https://api.github.com/users/nightroman/orgs","repos_url":"https://api.github.com/users/nightroman/repos","events_url":"https://api.github.com/users/nightroman/events{/privacy}","received_events_url":"https://api.github.com/users/nightroman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2017-12-26T18:24:32Z","updated_at":"2017-12-26T21:39:10Z","closed_at":null,"author_association":"NONE","body":"Runspace pools may cause memory leaks, at least in tested PowerShell v5, v6.\r\nPowerShell v2 does not have this issue.\r\n\r\nThe below script repeats a job infinitely in a loop. Run it and watch the\r\nprinted application handle counts and memory sizes. Stop scripts manually by\r\n<kbd>Ctrl+C</kbd> or close the PowerShell console.\r\n\r\nSteps to reproduce\r\n------------------\r\n\r\n```powershell\r\n# This script uses [PowerShell] with runspace pools. Printed handle and memory\r\n# numbers grow over time. Stop manually by Ctrl+C or close the console.\r\n# Otherwise you may run out of memory.\r\n\r\nfor() {\r\n    $pool = [RunspaceFactory]::CreateRunspacePool(1, 2)\r\n    $pool.Open()\r\n\r\n    $ps1 = [PowerShell]::Create()\r\n    $ps1.RunspacePool = $pool\r\n\r\n    $job1 = $ps1.AddScript('Get-Date').BeginInvoke()\r\n    $null = $job1.AsyncWaitHandle.WaitOne()\r\n    $result = $ps1.EndInvoke($job1)\r\n\r\n    $ps1.Dispose()\r\n    $pool.Close()\r\n\r\n    $p = Get-Process -Id $PID\r\n    \"$result Handles: $($p.HandleCount) Memory: $($p.PrivateMemorySize64 / 1mb) mb\"\r\n}\r\n```\r\n\r\nExpected behavior\r\n-----------------\r\n\r\nThe application used handle counts and memory sizes stay within reasonable ranges.\r\n\r\nActual behavior\r\n---------------\r\n\r\nThe application used handle counts and memory sizes grow over time,\r\npretty fast in this example due to leaks in the infinite loop.\r\n\r\nEnvironment data\r\n----------------\r\n\r\n```\r\n> $PSVersionTable\r\n\r\nName                           Value\r\n----                           -----\r\nPSVersion                      6.0.0-rc.2\r\nPSEdition                      Core\r\nGitCommitId                    v6.0.0-rc.2\r\nOS                             Microsoft Windows 10.0.15063\r\nPlatform                       Win32NT\r\nPSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}\r\nPSRemotingProtocolVersion      2.3\r\nSerializationVersion           1.1.0.1\r\nWSManStackVersion              3.0\r\n\r\nName                           Value\r\n----                           -----\r\nPSVersion                      5.1.15063.786\r\nPSEdition                      Desktop\r\nPSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}\r\nBuildVersion                   10.0.15063.786\r\nCLRVersion                     4.0.30319.42000\r\nWSManStackVersion              3.0\r\nPSRemotingProtocolVersion      2.3\r\nSerializationVersion           1.1.0.1\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/PowerShell/PowerShell/issues/comments/354015893","html_url":"https://github.com/PowerShell/PowerShell/issues/5746#issuecomment-354015893","issue_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/5746","id":354015893,"user":{"login":"rkeithhill","id":5177512,"avatar_url":"https://avatars1.githubusercontent.com/u/5177512?v=4","gravatar_id":"","url":"https://api.github.com/users/rkeithhill","html_url":"https://github.com/rkeithhill","followers_url":"https://api.github.com/users/rkeithhill/followers","following_url":"https://api.github.com/users/rkeithhill/following{/other_user}","gists_url":"https://api.github.com/users/rkeithhill/gists{/gist_id}","starred_url":"https://api.github.com/users/rkeithhill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkeithhill/subscriptions","organizations_url":"https://api.github.com/users/rkeithhill/orgs","repos_url":"https://api.github.com/users/rkeithhill/repos","events_url":"https://api.github.com/users/rkeithhill/events{/privacy}","received_events_url":"https://api.github.com/users/rkeithhill/received_events","type":"User","site_admin":false},"created_at":"2017-12-26T21:39:10Z","updated_at":"2017-12-26T21:39:10Z","author_association":"CONTRIBUTOR","body":"@potatoqualitee I would not generally recommend putting GC collect calls in production code because that subverts the GC's (generally good) algorithms for when a GC is needed.  But for memory hoard detection, it is useful to eliminate the \"non-determinism\" of the GC.\r\n\r\nAlso, if you call `RunspacePool.Dispose()` it [internally calls](https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs#L830) `Close()` so there is no need to call `Close()` before `Dispose()` AFAICT.\r\n\r\n@nightroman \r\n> Is this by design or a bug?\r\n\r\nThe [design guidelines](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern) say this:\r\n\r\n> ✓ CONSIDER providing method Close(), in addition to the Dispose(), if close is standard terminology in the area. \r\nWhen doing so, it is important that you make the Close implementation identical to Dispose and consider implementing the IDisposable.Dispose method explicitly. \r\n\r\nSince this is a \"guideline\" (CONSIDER vs DO or DO NOT), I wouldn't consider it a bug - bad form perhaps unless there is a way to re-open a closed RunspacePool but I don't see that functionality.\r\n\r\nP.S. Whenever I see \"DO or DO NOT\", I reflexively want to add \"there is no try\".  Hmm..."}}
{"actor":{"display_login":"rkeithhill"}}