2010-05-12 13 views
6

que tienen un muy pequeño servicio WCF alojado en una aplicación de consola.WCF Memoria Servicio Leaks

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    void DoService(); 
} 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)] 
public class Service1 : IService1 
{ 
    public void DoService() 
    { 

    } 
} 

y su ser llamado como

using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client()) 
{ 
    client.DoService(new DoServiceRequest()); 
    client.Close(); 
} 

Por favor, recuerde que el servicio se publica en basicHttpBindings.

Problema

Ahora, cuando he realizado anteriormente código de cliente en un bucle de 1000 me encontré gran diferencia entre "Todos los bytes del montón" y "Bytes privados" contadores de rendimiento (i utilizado .net perfilador de memoria). Después de la investigación me encontré con algunos de los objetos no están bien dispuestos siguientes son la lista de los objetos (se encontraron 1.000 instancia no vendida -> es igual a las llamadas del cliente)

(espacio de nombres para todos ellos es System.ServiceModel. canales)

HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream 
BodyWriterMessage 
BufferedMessage 
HttpRequestContext.ListenerHttpContext.ListenerContextHttpInput.ListenerContextInputStream 
HttpRequestContext.ListenerHttpContext 

Preguntas ¿Por qué tenemos gran cantidad de objetos no vendida y cómo controlarlos.

por favor ayuda

+1

Parece una pérdida de biblioteca del sistema para mí. El código del cliente (como en el servicio escrito por el usuario) no toca esos búferes y flujos, y parece que WCF no los descarta. –

+0

Mabushar: ¿Has tenido algo de suerte con esto? Parece que estoy teniendo un problema similar. – bugfixr

+0

@bugfixr lo siento hermano, he notado tu mensaje hoy, no recuerdo si fui capaz de deshacerme de ellos, pero una cosa que recuerdo fue que cambié al framework 4.0 del framework 3.5, me ayudó parcial o totalmente, no lo hice recuerda, pero me ayudó de alguna manera. lo siento por la respuesta tardía. –

Respuesta

0

Encontré la solución en 2010, pero me olvidé de publicarla. De hecho, perdí la pista exacta, pero recuerdo que fue un error de la biblioteca .Net que se informó a Microsoft y fue reconocido por ellos. No tengo su enlace, pero lo publicaría tan pronto como lo encuentre. De todos modos Microsoft ha solucionado este problema en .NET 4.0 y esa es la solución exacta que seguí, sé que para algunos de ustedes podría no ser posible debido a que el cambio en el entorno del servidor a veces no está en sus manos.

4

Usted está solicitando una nueva instancia por llamada (InstanceContextMode = InstanceContextMode.PerCall). Si no hay GC ocurriendo en las 1000 llamadas, las instancias del servicio no se recogerán. WCF requiere implementar IDisposable

De MSDN : Discover Mighty Instance Management Techniques For Developing WCF Apps

por llamada por llamada son el modo por defecto de instancias de Windows Communication Foundation. Cuando el tipo de servicio está configurado para la activación por llamada, una instancia de servicio, un objeto de tiempo de ejecución de lenguaje común (CLR), existe solo mientras una llamada de cliente está en progreso. Cada solicitud del cliente obtiene una nueva instancia de servicio dedicado. La Figura 2 ilustra cómo funciona esta activación de llamada única.

Figure 2 Per-Call Instantiation http://i.msdn.microsoft.com/cc163590.fig02(en-us).gif

  1. El cliente llama al proxy y el proxy envía la llamada al servicio .
  2. Windows Communication Foundation crea una instancia de servicio y llama al método en él.
  3. Después de la llamada devuelve el método, si el objeto implementa IDisposable , entonces Windows Communication Foundation llama IDisposable.Dispose en él.
+1

He visto este artículo antes y es cierto que llama al método Dispose automáticamente si hay alguno y esto es solo si ha abierto algunos recursos usted mismo y necesita limpieza, en este caso debe limpiarlos usted mismo. Pero en mi caso no tengo recursos para limpiar. Sin embargo, ya lo he intentado pero el mismo resultado. Además, me gustaría decirte que GC ha limpiado el Heap pero la memoria nativa no se limpia debido a que esos objetos fueron recolectados. –

1

¿Por casualidad ha habilitado los contadores de rendimiento? ¿Como abajo?

<system.serviceModel> 
    <diagnostics performanceCounters="All" /> 
    .. 
</system.serviceModel> 

En el apartado "El aumento de tamaño de la memoria de contadores de rendimiento", desde este enlace: http://msdn.microsoft.com/en-us/library/ms735098.aspx

hay mención de un Bytes privados "delincuentes" a contar cuando se habilitan los contadores de rendimiento de WCF. Cambiarlo a ServiceOnly o completamente deshabilitarlo (Off) puede hacer el truco.