【问题标题】:How bad is it to not dispose() in Powershell?不在 Powershell 中 dispose() 有多糟糕?
【发布时间】:2011-01-01 06:34:44
【问题描述】:

有时我们需要在 SharePoint 中执行小型管理任务。一个简单的 PowerShell 脚本是一个非常好的工具。例如,这样的脚本可以枚举列表的事件处理程序:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = new-object Microsoft.SharePoint.SPSite($args[0])   
$site.RootWeb.Lists["MyList"].EventReceivers > C:\MyListHandlers.txt

众所周知,SPSiteSPWeb 这样的对象在调用后必须是Dispose()-d,否则会发生内存泄漏。最好是打电话

$site.RootWeb.dispose()
$site.dispose()

在此脚本的末尾。但是,如果这是一个只运行一次的 Powershell 脚本,并且我们知道 PowerShell 在执行后会清理 - 不调用 dispose() 是不是很糟糕?

所以,我的问题是 - 如果有时我运行这样的脚本会不会有危险?它会影响 SharePoint 场(或我运行脚本的服务器)的整体稳定性吗?

【问题讨论】:

  • 很棒的工具,但它闻起来像 Perl,让我望而却步;)
  • 这是我的第一印象,但它允许使用任何 .net 类而无需编译等。

标签: powershell sharepoint sharepoint-2007 dispose


【解决方案1】:

已对其进行了编辑,以包含一个安全、非特定的答案。

IN GENERAL:处理所有内容,因为 Dispose 是 .NET 框架释放外部资源(例如文件句柄、TCP 端口、数据库连接等)的方式。除非您调用 Dispose(),否则不保证会释放资源。所以要小心。这是一般的非 SharePoint 答案。

特别是在处理 SharePoint 时: 当您关闭 PowerShell.exe 进程时,将释放内存。如果您需要处置对象以降低内存压力(在生产环境中很重要,或者如果您正在遍历所有站点/网站),请确保处置。如果没有,您无需担心处置。

我们之所以如此热衷于首先进行处置是因为大多数 SharePoint 代码在长时间运行的进程中运行(在 ASP.NET 工作进程或 OWSTimer.exe 中),而未能处置可能会导致困难——故障排除,突然的灾难(即,网络服务器繁荣)。在 PowerShell 中工作时,这些灾难性的性能问题/OutOfMemoryExceptions 不会影响我的大部分时间。我运行临时脚本,浪费了大约 3-50MB 的 RAM,因为我没有处理我的对象,我关闭了 PowerShell 窗口并释放了内存。 大多数情况下这不是问题。

我已经构建了使用 SharePoint 的脚本,而且大部分时间我都懒得处理。

Here is a script wherein I dispose SPSite and SPWeb objects

Here is a script in which I don't bother to dispose an SPSite object

【讨论】:

  • 感谢您的回答。顺便说一句,这些链接中的脚本很好。
  • 谢谢!有一个不错的CodePlex项目,收集了几十个SP相关的脚本:sharepointpsscripts.codeplex.com
  • 实际上这并不完全正确 - 当进程结束时,是的,内存被释放,但既不调用 Dispose 也不调用 Finalize。这完全取决于对象在 Dispose 中的作用,但实际上,这种区别可能并不重要。
  • @Peter,你有任何参考资料可以支持吗?
  • 我是自引用的,不需要引用任何更高的权威。不过说真的,打开任务管理器,通过任务管理器关闭PowerShell.exe进程,看看会发生什么。
【解决方案2】:

理想情况下,您应该尽可能调用 Dispose。甚至在 PowerShell 内部。

SharePoint 库包含大量代码,这些代码只是对 COM 对象的包装 - 为了让生活更有趣,其中许多 COM 对象都有自己的池和缓存。对 Dispose 的 .NET 调用实际上只是指示 COM 对象它们可以释放自己的对象(这些对象的生命周期可能在调用进程之外)。

这里有一些更相关的信息:http://blogs.msdn.com/sharepoint/archive/2009/02/11/sharepoint-and-powershell-knowledge.aspx

【讨论】:

    【解决方案3】:

    只要关注this

    即使它是一个简单的脚本,一旦执行就会释放内存,你永远不知道在某个时候它是否会被复制/粘贴到更大脚本的内部循环中:-)

    为了正确起见,您应该始终按照上面链接中的说明处置 SP 对象。

    【讨论】:

    • 关于被复制/粘贴到更大的脚本中的意义是非常正确的。我见过一些管理员制作的脚本,它们是在网络上发现的不同脚本的组合,“作为副作用”也执行了管理员当时需要的事情 ;-)
    【解决方案4】:

    如果 shell 访问的外部资源的生命周期比 PowerShell 脚本的生命周期长,那么它应该调用 Dispose。

    但是,如果是脚本分配的资源,则无需清理。当脚本退出时,所有分配给脚本的内存都会被清理掉。

    【讨论】:

    • 这不是真的。即使它是由脚本分配的,它也可能会导致内存不足的异常。 (为什么人们将脚本视为低级公民?☺)
    【解决方案5】:

    虽然关闭进程会清理一切,但要小心。如果您要执行涉及农场中所有站点的循环,则丢失的处置可能会迅速消耗大量内存,这将使您的服务器缓慢爬行。由于脚本对批处理操作最有帮助,因此请始终牢记这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      • 2010-11-24
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多