¿Fuga de memoria en .Net Speech.Synthesizer?

Encontré una fuga continua en mi aplicación. Después de examinar usando un generador de perfiles de memoria, descubrí que el curso es un objeto de Microsoft Speech.Synthesizer

Así que construyo un proyecto de juguete para verificar la hipótesis:

//Ejemplo de juguete para mostrar pérdida de memoria en el objeto Speech.Synthesizer

static void Main(string[] args)
{
    string text = "hello world. This is a long sentence";
    PromptBuilder pb = new PromptBuilder();
    pb.StartStyle(new PromptStyle(PromptRate.ExtraFast));
    pb.AppendText(text);
    pb.EndStyle();
    SpeechSynthesizer tts = new SpeechSynthesizer();

while (true)
{
    //SpeechSynthesizer tts = new SpeechSynthesizer();
    Console.WriteLine("Speaking..."); 
    tts.Speak(pb);

    //Print private working set sieze
    Console.WriteLine("Memory: {0} KB\n", (Process.GetCurrentProcess().PrivateMemorySize64 / 1024).ToString("0"));

    //tts.Dispose();    //also this doesn't work as well
    //tts = null;

    GC.Collect();   //a little help, but still leaks
}
}

Y el resultado en realidad confirmó que la pérdida de memoria es de Speech.Synthesizer

Speaking...

Memoria: 42184 KB

Hablando... Memoria: 42312 KB

Hablando... Memoria: 42440 KB

Hablando... Memoria: 42568 KB

Hablando... Memoria: 42696 KB

Hablando... Memoria: 42824 KB

Hablando... Memoria: 43016 KB

Hablando... Memoria: 43372 KB

Lo busqué en Google y descubrí que muchos otros se han encontrado con el mismo problema: 1: Pérdida de memoria constante en SpeechSynthesizer 2: http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak

pero lamentablemente no encontré ninguna solución. Dado que es un problema que ya se planteó hace mucho tiempo, entonces quiero preguntar si se resolvió o no.

Muchas gracias.

ACTUALIZACIÓN:

Parece que mientras cambio a usar SAPI COM dll en lugar del paquete .Net Speech.Synthesizer (aunque esencialmente son lo mismo), la memoria deja de tener fugas.

¿Por qué los dos comportamientos de invocación (SAPI dll vs .net Speech package) tienen un comportamiento de memoria diferente? Como parece, este último es solo un envoltorio para el antiguo SAPI dll.

    static void Test2()
{
    //SAPI COM component this time
    SpeechLib.SpVoiceClass tts = new SpeechLib.SpVoiceClass();
    tts.SetRate(5);
    string text = "hello world. This is a long sentence";
    //tts.Speak("helloWorld", SpeechLib.SpeechVoiceSpeakFlags.SVSFDefault);
while (true)
{

    Console.WriteLine("Speaking...");
    tts.Speak(text, SpeechLib.SpeechVoiceSpeakFlags.SVSFDefault);

    //Print private working set sieze
    Console.WriteLine("Memory: {0} KB\n", (Process.GetCurrentProcess().PrivateMemorySize64 / 1024).ToString("0"));

    GC.Collect();
}

}

Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

Hablando... Memoria: 32044 KB

preguntado el 22 de mayo de 12 a las 18:05

3 Respuestas

Solución final:

Buscar en Google palabras clave relevantes diciéndome que en realidad es un error de Microsoft.

Parece que mientras cambio a usar SAPI COM dll en lugar del paquete .Net Speech.Synthesizer (aunque esencialmente son lo mismo), la memoria deja de tener fugas.

Respondido el 26 de junio de 12 a las 22:06

¿Puedes publicar alguno de esos enlaces? ¿Hay un problema de MS Connect para ello? - código kaizen

@codekaizen Sí, en realidad leí el informe de algunos usuarios en el foro de MS, la publicación se publicó hace dos años. Por eso llego a tal conclusión. Tendré que buscar de nuevo la publicación que leí el mes pasado... - JXITC

No estoy seguro de todos los detalles sobre SpeechSynthesizer, pero podría intentar usar el patrón desechable aquí. Dado que SpeechSynthesizer implementa Desechable

Su código se vería así:

while (true)
{
   using (SpeechSynthesizer tts = new SpeechSynthesizer())
   {
      Console.WriteLine("Speaking..."); 
      tts.Speak(pb);

      //Print private working set sieze
      Console.WriteLine("Memory: {0} KB\n",(Process.GetCurrentProcess().PrivateMemorySize64 / 1024).ToString("0"));
   }
}

Si nota que esto es muy similar al ejemplo de Microsoft Aquí

De hecho, esto parece ser una pérdida de memoria. ¿Ha intentado usar el Tiempo de ejecución de Microsoft.Speech? La sintaxis se ve muy similar y lo han mencionado. no debe tener el mismo problema

contestado el 22 de mayo de 12 a las 19:05

Gracias :) pero todavía tiene pérdidas de memoria - JXITC

Parece entonces basado en la propia admisión de Microsoft de estas filtraciones. Ver Editar arriba. - Kyle c

¿Por qué los dos comportamientos de invocación (SAPI dll vs .net Speech package) tienen un comportamiento de memoria diferente? Como parece, este último es solo un envoltorio para el antiguo SAPI dll. - JXITC

No estoy seguro, me estoy saliendo de lo que dijo un representante de Microsoft aquí: connect.microsoft.com/VisualStudio/feedback/details/664196/… - Kyle c

Sé que es un hilo viejo, pero hay otra solución para el problema. Usar Microsoft.Speech.Synthesis.SpeechSynthesizer en lugar de Sistema.Speech.Synthesis.SpeechSynthesizer.

Microsoft.Speech.Synthesis.SpeechSynthesizer está incluido en el Microsoft Speech Platform - Kit de desarrollo de software (SDK) (Versión 11) - https://www.microsoft.com/en-us/download/details.aspx?id=27226

Esta versión del sintetizador no tiene pérdida de memoria.

contestado el 08 de mayo de 18 a las 09:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.