2011-05-03 5 views
5

He escrito un .Net (2.0) de servicio de Windows utiliza para enviar mensajes de buscapersonas a los usuarios (a través de conexiones de puerto serie a un hardware tercera parte)..Net 2.0 servicio de Windows se bloquea durante la recolección de basura

El servicio consulta periódicamente una base de datos (OS PI Historian), analiza los valores y decide si se envía un mensaje en función de los valores pares.

El servicio utiliza un objeto de búsqueda (cuyos valores provienen de una base de datos de SQL Server y se actualiza cada minuto) para obtener los valores de la dirección del usuario y la cadena del mensaje para enviar.

El servicio utiliza una cantidad de Threading.Timer para activar las llamadas a bases de datos periódicas y los envíos de mensajes.

El servicio se instala en una máquina Windows 2003 que tiene instalado .Net 2 SP2.

El servicio funciona bien durante una semana y luego se cuelga. No se registran excepciones dentro del registro (log4net).

que tienen tomar una serie de vertederos desde el servidor y todos ellos presentan las mismas características - un hilo desencadena GC, pero se bloquea completamente:

06aaf06c 7c827b99 77e61d1e 00004acc 00000000 ntdll!KiFastSystemCallRet 
06aaf070 77e61d1e 00004acc 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc 
06aaf0e0 79e8c5f9 00004acc ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xac 
06aaf124 79e8c52f 00004acc ffffffff 00000000 mscorwks!PEImage::LoadImage+0x1af 
06aaf174 79e8c54e ffffffff 00000000 00000000 mscorwks!CLREvent::WaitEx+0x117 
06aaf188 79f2f88f ffffffff 00000000 00000000 mscorwks!CLREvent::Wait+0x17 
06aaf1a8 79f2f8ca 7a3b9020 00000000 ffffffff mscorwks!SVR::gc_heap::user_thread_wait+0x50 
06aaf1b8 79f2f806 00000000 7a3b8b18 00080101 mscorwks!WKS::gc_heap::wait_to_proceed+0xe 
06aaf1cc 79f92f5a 00000000 00000000 00000000 mscorwks!WKS::gc_heap::garbage_collect+0x247 
06aaf1f8 79f94e26 00000000 00000000 00000030 mscorwks!WKS::GCHeap::GarbageCollectGeneration+0x1a9 
06aaf284 79f926ce 052c75c8 00000030 00000000 mscorwks!WKS::gc_heap::try_allocate_more_space+0x15b 
06aaf298 79f92769 052c75c8 00000030 00000000 mscorwks!WKS::gc_heap::allocate_more_space+0x11 
06aaf2b8 79e73291 052c75c8 0000002e 00000000 mscorwks!WKS::GCHeap::Alloc+0x3b 
06aaf2d4 79e7d8d4 0000002e 00000000 00000000 mscorwks!Alloc+0x60 
06aaf310 79e99056 0000000f b456b75e 00001ce3 mscorwks!SlowAllocateString+0x29 
06aaf3b4 792bb2c1 00000000 0108082b 00001f40 mscorwks!FramedAllocateString+0xa1 
    Stack shortened for bravity... 

pila Gestionado:

ESP  EIP  
06aaf364 7c82847c [HelperMethodFrame: 06aaf364] 
06aaf3bc 792bb2c1 System.String.CreateStringFromEncoding(Byte*, Int32, System.Text.Encoding) 
06aaf3dc 792aaf2a System.Text.EncodingNLS.GetString(Byte[], Int32, Int32) 
06aaf3fc 6522d131 System.Data.SqlClient.TdsParserStateObject.ReadStringWithEncoding(Int32, System.Text.Encoding, Boolean) 
06aaf41c 656ca93e System.Data.SqlClient.TdsParser.ReadSqlStringValue(System.Data.SqlClient.SqlBuffer, Byte, Int32, System.Text.Encoding, Boolean, System.Data.SqlClient.TdsParserStateObject) 
06aaf448 6522d925 System.Data.SqlClient.TdsParser.ReadSqlValue(System.Data.SqlClient.SqlBuffer, System.Data.SqlClient.SqlMetaDataPriv, Int32, System.Data.SqlClient.TdsParserStateObject) 
06aaf474 656208b7 System.Data.SqlClient.SqlDataReader.ReadColumnData() 
06aaf484 65620962 System.Data.SqlClient.SqlDataReader.ReadColumn(Int32, Boolean) 
06aaf4b4 65221415 System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32) 
06aaf4c8 652213af System.Data.SqlClient.SqlDataReader.GetValue(Int32) 
06aaf4f8 65220aec System.Data.SqlClient.SqlDataReader.get_Item(System.String) 
06aaf504 03616b81 AlarmEventCollator.DataAccess.GetAllAlarmDetails() 
06aaf564 03616a28 AlarmEventCollator.AlarmBuilder.buildLookups() 
06aaf590 0361aa89 AlarmEventCollator.AlarmBuilder.pollLookups(System.Object) 
06aaf5d0 792a83ff System.Threading._TimerCallback.TimerCallback_Context(System.Object) 
06aaf5d8 792e019f System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
06aaf5f0 792a836b System.Threading._TimerCallback.PerformTimerCallback(System.Object) 
06aaf77c 79e71b4c [GCFrame: 06aaf77c] 

El GC generalmente sucede en los métodos de análisis de base de datos. Todos los otros subprocesos administrados parecen bloquearse, lo que sería coherente con el proceso de GC.

Le agradecería cualquier punteros. Más información disponible a petición.

+0

Usted está tratando con una gran cantidad de diferentes conexiones (SQL y de serie). ¿El GC puede recoger todos los elementos antiguos o hay algo retenido en la memoria que causaría un aumento en el uso de la memoria (las clases estáticas o conexiones en serie podrían causar esto si no tiene cuidado)? ¿Has visto el uso de la memoria para asegurarte de que no es tan simple como que el GC no tiene la capacidad de funcionar porque la memoria está demasiado llena (pregunta estúpida, lo sé, pero tengo que preguntar)? – IAmTimCorey

+1

Además, asegúrese de que está desechando todos los objetos que implementan IDisposable tan pronto como haya terminado con ellos. –

+0

No creo que haya ningún objeto grande excesivo en la memoria: el volcado de bloqueo informa que tiene un tamaño de pila de 22mb.Por lo que puedo decir, todos los objetos IDisposibles están siendo eliminados. –

Respuesta

2

¿Cuántos subprocesos de GC tenemos en un proceso .NET que ejecuta la versión de Servidor del GC en una máquina de doble núcleo?

Dos, uno por procesador, o más bien uno por procesador lógico, por lo que habría sido 4 si estaba hiperhebra. En un proceso que ejecuta la versión de estación de trabajo del GC, no tendremos hilos de GC dedicados, sino que la recolección de basura se ejecuta en el hilo iniciando el GC ya que no tiene sentido cambiar a un hilo diferente para la recolección de basura cuando solo tiene un proceso/uno hilo haciendo el GC.

Chris Lyon tiene una buena reseña sobre los modos de GC y también una interesante publicación acerca de los modos de latencia de GC que vienen en Orcas.

¿Por qué es importante para usted? Dado que los diferentes modos de GC están optimizados para diferentes cosas, el uso de la memoria, la latencia del GC, etc. pueden variar mucho según el modo de GC que esté utilizando. Por ejemplo, un servicio de Windows obtiene de manera predeterminada la estación de trabajo GC, pero si hay una gran cantidad de througput (muchos alocs de vida corta), probablemente sea mucho mejor ejecutar el servidor GC para el uso de la memoria y el rendimiento.

+0

Sí, solucioné este problema al configurar el modo GC en Servidor. Parece que por alguna razón el GC estaba teniendo problemas de rendimiento/confiabilidad en el modo Estación de trabajo. –

+0

Si esto resuelve, ¿puede marcar eso como respuesta y cerrarlo? – Ramprasad

Cuestiones relacionadas