Archivo de la etiqueta: Memory Leak

Como usar SPDisposeCheck con SharePoint 2010

Una buena práctica cuando se desarrolla sobre SharePoint 2010 es el control de la destrucción de objetos no manejados (objetos COM) en memoria (como pueden ser los objetos SPSite y SPWeb).

SharePoint mezcla objetos manejados como no manejados, por lo que tenemos que tener muy claro cuales son cada uno de ellos, y como debemos destruirlos después de haberlos usado.

Para tener claro y conocer las buenas practicas indicadas por Microsoft, sobre como eliminar objetos de SharePoint o dejo este enlace: Best Practices: Using Disposable Windows SharePoint Services Objects, creo que es un articulo que todo desarrollador debería leer y tener claro.

Para poder llevar a la practica estas instrucciones o reglas, existe una herramienta que nos permite detectar estas posibles fugas de memoria, desde Visual Studio 2008/2010 llamada SPDisposeCheck como un add-in más. Se puede descargar desde aquí: http://archive.msdn.microsoft.com/SPDisposeCheck

¿Como podemos usar SPDisposeCheck?

1) Una vez nos hemos descargado la aplicación y hemos instalado en nuestro entorno de desarrollo, paramos a configurarla… abrimos el Visual Studio 2008/2010, en el menú de herramientas nos vamos a “Toos” y ahí veremos un nuevo elemento llamado “SharePoint Dispose Check”

2) Abrimos la herramienta debemos rellenar los campos “Path to SPDisposeCheck” que es la ruta donde hemos instalado la herramienta y el campo “Treat problems as” yo siempre prefiero “Warnings” en vez de “Errors”. Luego guardas y ya esta finalizada la configuración.

3) Una vez finalizada la configuración, solo queda realizar una prueba (usando un código incorrecto)… créate una aplicación de consola, añade la referencia a la librería Microsoft.SharePoint y usa el siguiente código:

SPSite site = new SPSite("http://server");
SPWeb web = site.OpenWeb();
String str = web.Title;

Una vez lo tengamos, solo tenemos que compilar, y ver que el compilador nos muestra dos warnings:

4) Si cambiamos nuestro codigo anterior por este otro (utilizando using para la instancia de objetos) veremos como desaparecen las advertencias:

using (SPSite site = new SPSite("http://server")) 
{
  using (SPWeb web = site.OpenWeb())
  {
	String str = web.Title;
  }
}

Gracias a herramienta podemos corregir nuestras implementaciones sobre SharePoint 🙂

Otra funcionalidad que os puede venir bien, es la posibilidad de pasar la herramienta SPDisposeCheck directamente a un DLL. Esto os sera muy útil en el caso de tener que comprobar algún “memory leak” o perdidas de memoria con librerias de un entorno de Producción, solo hay que ejecutar desde linea de comandos SPDisposeCheck, pasandole como parametro la ruta de la DLL que quieres analizar. Aqui os dejo los parametros que admite por linea de comandos:

Usage:

  SPDisposeCheck.exe  [options]

Options:

  -?    Display command-line help
  -od   Display only the Sharepoint types that have been disposed e.g. the "Do Not Dispose" violations
  -ond  Display only the Sharepoint types that have not been disposed e.g. the "Dispose" violations
  -xml  Display output as XML

 

 

Script para habilitar CollectSPRequestAllocationCallStacks en SharePoint 2010

Una tarea que ha de realizar cualquier desarrollador de SharePoint 2010 es la labor de revisar los logs en los diferentes entornos de los que se cuenta…

Revisando los logs de ULS con la aplicación ULS Viewer (verdaderamente útil), me he encontrado con este mensaje de error relacionado con un memory leak (perdida de memoria):

An SPRequest object was not disposed before the end of this thread.
To avoid wasting system resources, dispose of this object or its
parent (such as an SPSite or SPWeb) as soon as you are done using it.
This object will now be disposed.  Allocation Id:
{646667A7-73BC-4DDD-B0FB-6EDFC315CCE7}  To determine where this
object was allocated, set
Microsoft.SharePoint.Administration.SPWebService.ContentService.CollectSPRequestAllocationCallStacks = true.

Este es un mensaje que no nos da mucha información sobre el objeto que esta generando la perdida de memoria al no ser liberado… para obtener mas información lo que debemos hacer es ver la pila de llamadas actual.

Para ello y como se especifica en la descripción del error, lo que debemos hacer es activar la propiedad CollectSPRequestAllocationCallStacks, para ello, lo mas sencillo es usar un script de PowerShell:

$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
write-host "Actual: " $contentService.CollectSPRequestAllocationCallStacks
$contentService.CollectSPRequestAllocationCallStacks = $true
$contentService.Update()
write-host "Nuevo: " $contentService.CollectSPRequestAllocationCallStacks

Una vez hayamos realizado el cambio podemos volver a revisar los logs de ULS y ahora comprobaremos que nos muestra toda la información de la pila sobre el objeto que no esta siendo liberado.