2016-01-23 107 views
0

使用Powershell v3,我使用.net库类System.DirectoryServices.DirectoryEntrySystem.DirectoryServices.DirectorySearcher来查询域中用户的属性列表。这个代码基本上是found here新对象是否有内存泄漏?

您需要添加的唯一东西是行和$ds.PropertiesToLoad.AddRange($properties)之间的行$ds.PageSize=1000。这将消除只抓取1000个用户的限制。

来自一个域的用户数(我们称之为domain1)我已经有超过80,000个用户。另一个域名(我们称之为domain2)拥有超过20万用户。

如果我在domain1上运行代码,大约需要12分钟(与使用的24小时Get-QADUser相比,这太棒了)。但是,脚本在PowerShell窗口中完成后,我注意到内存猪剩下约500MB。 Domain2留下了大约1.5gb的记忆猪。

注:Get-QADUser内存泄漏是非常非常更糟糕Domain2留下了大约6GB的内存猪,大约需要72小时才能完成(而.NET类不到一个小时)。

释放内存的唯一方法是关闭PowerShell窗口。但是如果我想写一个脚本来调用所有这些域脚本来一个接一个地运行它们呢?到达第六个脚本后,我会耗尽内存。

我能想到的唯一的事情是New-Object正在创建构造函数并且没有析构函数(与java不同)。我在循环迭代期间尝试使用[System.GC]::Collect(),但这没有任何影响。

是否有原因?它是可解决的还是我坚持这个?

+0

我手边没有答案,但我可以告诉你你看到的不是特定于“新对象”的。即使使用'Get-Content'在一个.ps1文件运行时将大量数据存储在一个变量中,似乎将数据缓存在内存中,即使该变量不直接可用(除非声明范围或点源)完成运行。我不认为你所看到的是真正的内存泄漏。这是正常的。” –

回答

1

有一点需要注意:如果实际上是内存泄漏,你可以运行该脚本在新shell:

powershell { <# your code here #> } 

至于泄漏,只要你有一个引用的变量持有大数据的对象无法收集。通过使用内存分析器查看内存中的内容和原因,您可能会有好运。据我所见,如果您在脚本文件中使用该代码并执行脚本(&,而不是.!),那么这应该不会发生。

+0

不幸的是,由于公司限制我们不使用任何工具,程序,编译器或其他任何东西(包括来自Microsoft的rsat工具),因此我无法使用内存分析器。幸运的是,IT安装了.net,因此我可以使用这些库。我唯一允许使用的是Power GUI和Powershell v3(我甚至无法升级到v5)。我会尝试在新的powershell过程中执行代码的建议,并看看如何。谢谢。 –

+0

这一定会正常工作,内存被清除。我只需要弄清楚如何通过参数传递给它。 –

+0

@FiddleFreak:只需通过他们。如果您正在调用脚本,则只需附加参数,例如'powershell -File foo.ps1 arg1 arg2 ...'。 – Joey

0

我想这是使用所有内存的$table。为什么不直接将收集的数据写入文件,而是将其添加到数组中?