在Powershell中没有处置()有多糟糕?

时间:2010-01-04 14:31:38

标签: powershell sharepoint sharepoint-2007 dispose

有时我们需要在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场(或我运行脚本的服务器)的整体稳定性吗?

5 个答案:

答案 0 :(得分:17)

这已被编辑为包含安全,非特定的答案。

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:3)

只需关注this

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

为了正确起见,您应该始终按上述链接中的规定处理SP对象。

答案 3 :(得分:2)

如果shell正在访问一个生命周期超过PowerShell脚本生命周期的外部资源,那么它应该调用Dispose。

但是,如果它是脚本分配的资源,则无需清理。当脚本退出时,将清除为脚本分配的所有内存。

答案 4 :(得分:2)

虽然关闭过程会清理,但要小心。如果您要执行涉及服务器场中所有站点的循环,则丢失的部署会很快占用大量内存,从而导致服务器速度变慢。由于脚本编写对批处理操作最有帮助,因此请始终牢记这一点。