【问题标题】:Does New-Object have a memory leak?New-Object 是否存在内存泄漏?
【发布时间】:2016-01-25 09:31:26
【问题描述】:

使用 Powershell v3,我使用 .net 库类 System.DirectoryServices.DirectoryEntry 和 System.DirectoryServices.DirectorySearcher 来查询域中用户的属性列表。这个代码基本上是found here。

您唯一需要添加的是$ds.PageSize=1000 行$ds.Filter = '(&(objectCategory=person)(objectClass=user))' 和$ds.PropertiesToLoad.AddRange($properties) 之间的行。这将取消仅抓取 1000 个用户的限制。

我拥有的一个域(我们称之为domain1)的用户数量超过了80,000。另一个域(我们称之为domain2)拥有超过 200,000 个用户。

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

注意:Get-QADUser 的内存泄漏要严重得多。 Domain2 会占用大约 6GB 的内存,大约需要 72 小时才能完成(而 .net 类则不到一个小时)。

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

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

有什么原因吗?它是可以解决的还是我被困住了?

【问题讨论】:

  • 我没有即兴的答案,但我可以告诉你,你所看到的并不特定于 New-Object。即使在从 .ps1 文件运行时使用Get-Content 将大量数据存储在变量中进行简单测试,似乎也会将数据缓存在内存中,即使该变量不能直接使用(除非声明范围或点采购)当它完成运行时。我不认为你看到的是真正的内存泄漏。这是“正常的”。

标签: powershell memory-leaks powershell-3.0


【解决方案1】:

需要注意的一点:如果确实存在内存泄漏,您可以在新的 shell 中运行脚本:

powershell { <# your code here #> }

至于泄漏,只要您有任何变量引用了持有大数据的对象,就无法收集它。使用内存分析器查看仍在内存中的内容以及原因可能会让您很幸运。据我所知,如果您在脚本文件中使用该代码并执行脚本(使用&amp;,而不是使用.!),那么这不应该真的发生。

【讨论】:

  • 不幸的是,我不能使用内存分析器,因为公司限制我们使用任何工具、程序、编译器或任何尚未附带的工具、程序、编译器或任何东西(包括微软的 rsat 工具) IT设置的电脑。幸运的是,IT 安装了 .net,所以我可以使用这些库。我唯一可以使用的是 Power GUI 和 Powershell v3(我什至无法升级到 v5)。不过,我将尝试在新的 powershell 进程下执行代码的建议,看看效果如何。谢谢。
  • 这绝对有效并且内存被清除了。我只需要弄清楚如何将参数传递给它。
  • @FiddleFreak:正常通过就好了。如果您正在调用脚本,则只需附加参数,例如powershell -File foo.ps1 arg1 arg2 ....
【解决方案2】:

我猜是$table 正在使用所有内存。为什么不直接将采集到的数据写入文件,而不是添加到数组中呢?

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 2011-01-29
    • 2011-05-08
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 2011-06-26
    • 2011-10-07
    • 1970-01-01
    相关资源
    最近更新 更多