Memory leak in .Net Speech.Synthesizer?

I found a continuous leak in my application. After examining the use of the memory profiler, I found that there was some kind of object from Microsoft Speech. Synthesizer

So, I am creating a toy project to test the hypothesis:

// Example game to show a memory leak in a 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 } } 

And the result actually confirmed a memory leak from Speech.Synthesizer

 Speaking... 

Memory: 42184 KB

Speaking ... Memory: 42312 KB

Speaking ... Memory: 42440 KB

Speaking ... Memory: 42568 KB

Speaking ... Memory: 42696 KB

Speaking ... Memory: 42824 KB

Speaking ... Memory: 43016 KB

Speaking ... Memory: 43372 KB

I searched for it and found that many others are facing the same problem: 1: Persistent memory leak in SpeechSynthesizer 2: http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has- a-memory-leak

but, unfortunately, I did not find any solution for him. Since his problem has long been asked, so I want to ask if it is resolved or not?

Many thanks.

UPDATE:

It seems that if I switch to using the SAPI COM dll and not the .Net Speech.Synthesizer package (although, in fact, this is the same thing), the memory stops leaking.

Why do two invoke behaviors (SAPI dll vs .net Speech package) have different memory behavior? As it seems to the latter, this is just a shell for the old 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(); } 

}

Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

Speaking ... Memory: 32044 KB

+7
source share
2 answers

Final decision:

Google relevant keywords tell me that this is actually a bug from Microsoft.

It seems that if I switch to using the SAPI COM dll and not the .Net Speech.Synthesizer package (although, in fact, this is the same thing), the memory stops leaking.

+3
source

I'm not sure about the details in SpeechSynthesizer, but you can try using a one-time template here. Since SpeechSynthesizer implements IDisposable

Your code will look like this:

 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")); } } 

If you notice that this is very similar to the Microsoft example Here

Apparently this is a memory leak. Have you tried using Microsoft.Speech runtime ? The syntax looks very similar, and they mentioned that it should not have the same problem.

+3
source

All Articles