2010-01-04 15 views
29

A veces necesitamos realizar pequeñas tareas administrativas en SharePoint. Un simple script de PowerShell es una herramienta realmente buena para eso. Por ejemplo, tales script puede enumerar controladores de eventos de una lista:¿Qué tan malo es no desechar() en Powershell?

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

Es conocido que los objetos como SPSite y SPWeb tienen que ser Dispose() -d después de una llamada, de lo contrario se producen pérdidas de memoria. Lo mejor sería llamar al

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

al final de este script. Pero si se trata de un script de Powershell que solo se ejecutará una vez, y sabemos que PowerShell se limpia después de la ejecución, ¿es tan malo no llamar a disponer()?

Entonces, mi pregunta es: ¿hay algún peligro si a veces ejecuto scripts como este; ¿afectará la estabilidad general de la granja de SharePoint (o del servidor en el que estoy ejecutando la secuencia de comandos)?

+2

Gran herramienta pero huele como Perl y me mantiene alejado;) –

+3

Esa fue mi primera impresión, pero permite trabajar con cualquier clase .net sin compilar etc. – naivists

Respuesta

16

ha sido revisada para incluir una respuesta segura, no específica.

EN GENERAL: deseche todo, porque Dispose es la forma del .NET framework de liberar recursos externos (como manejadores de archivos, puertos TCP, conexiones a bases de datos, etc.). No se garantiza que los recursos se liberarán a menos que llame a Dispose(). Así que ten cuidado. Esta es la respuesta general que no es de SharePoint.

ESPECÍFICAMENTE cuando se trata de SharePoint: Cuando se cierra el proceso de PowerShell.exe, se libera la memoria. Si necesita desechar objetos para mantener la presión de la memoria baja (importante en entornos de producción o si está recorriendo todos los sitios/webs), asegúrese de desecharlos. Si no, no necesita preocuparse por deshacerse de él. El motivo por el que estamos tan locos por deshacernos de nosotros es porque la mayoría de los códigos de SharePoint se ejecutan en procesos de larga ejecución (en un proceso de trabajo ASP.NET o en OWSTimer.exe) y no pueden eliminarse. -para solucionar problemas, catástrofes repentinas (es decir, el servidor web se dispara). Estos problemas de rendimiento catastrófico/OutOfMemoryExceptions no me afectan la mayor parte del tiempo cuando trabajo en PowerShell. Ejecuto scripts ad-hoc, desperdicio ~ 3-50MB de RAM porque no puedo eliminar mis objetos, cierro la ventana de PowerShell y la memoria se libera. La mayoría de los del tiempo es un nonissue.

He creado scripts para trabajar con SharePoint, y la mayoría de las veces no me molesto en deshacerme de ellos.

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

Gracias por la respuesta. Niza secuencias de comandos en estos enlaces, por cierto. – naivists

+2

gracias! Hay un buen proyecto CodePlex que ha recopilado docenas de scripts relacionados con SP: http://sharepointpsscripts.codeplex.com –

+2

De hecho, eso no es exactamente cierto: cuando el proceso finaliza, sí, la memoria se libera pero no se llama Dispose ni Finalize. Todo depende de lo que hace el objeto en Dispose, pero en realidad, esta distinción probablemente no importe. – Josh

2

Si el shell está accediendo a un recurso externo que tiene una vida útil más larga que la duración del script de PowerShell, debe llamar a Dispose.

Sin embargo, si se trata de un recurso asignado por el script, no es necesario limpiarlo. Cuando sale la secuencia de comandos, se limpiará toda la memoria asignada para la secuencia de comandos.

+2

Esto no es cierto. Incluso si el script lo asigna, podría causar excepciones por falta de memoria en el futuro. (¿Por qué las personas tratan los guiones como ciudadanos de bajo nivel? ☺) – Ariel

4

Idealmente, debe llamar a Dispose cuando sea posible. Incluso dentro de PowerShell.

Las bibliotecas de SharePoint incluyen una gran cantidad de código que es solo una envoltura alrededor de los objetos COM, y para hacer la vida más divertida, muchos de esos objetos COM tienen sus propios pools y caches. La llamada .NET a Dispose realmente solo indica a los objetos COM que pueden liberar sus propios objetos (que pueden tener una vida útil fuera del proceso de llamada).

Aquí hay alguna información más relevante: http://blogs.msdn.com/sharepoint/archive/2009/02/11/sharepoint-and-powershell-knowledge.aspx

2

Mientras se cierra el proceso va a limpiar las cosas, tenga cuidado. Si tuviera que hacer un ciclo que involucre a todos los sitios de su granja, una disposición que falte rápidamente puede consumir una cantidad significativa de memoria que ralentizará su servidor a paso de tortuga. Dado que las secuencias de comandos son más útiles para las operaciones por lotes, siempre tenlo en cuenta.

3

Solo siga this.

Incluso si es un simple script que libera la memoria una vez ejecutado, nunca se sabe si en algún momento que va a ser copiar/pegar en un bucle interno de un guión más grande :-)

Para la corrección, siempre se debe disponga los objetos SP como se especifica en el enlace de arriba.

+1

El punto de ser copiar/pegar en un script más grande es muy cierto. He visto guiones realizados por algunos administradores, una combinación de diferentes guiones encontrados en la web que "como efecto secundario" también realizan lo que el administrador necesita en ese momento ;-) – naivists

Cuestiones relacionadas