.Net Speech.Synthesizer中的内存泄漏?

我在申请中发现了连续泄漏。 在使用内存分析器进行检查后,我发现该课程是来自Microsoft Speech.Synthesizer的一些对象

所以我建立了一个玩具项目来validation这个假设:

//在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 } } 

结果实际上确认了内存泄漏来自Speech.Synthesizer

 Speaking... 

内存:42184 KB

说到……内存:42312 KB

说到……内存:42440 KB

说到……内存:42568 KB

说到……记忆:42696 KB

说到……内存:42824 KB

说到……内存:43016 KB

说到……内存:43372 KB

我用Google搜索并发现其他许多人遇到了同样的问题:1: SpeechSynthesizer 2中的常量内存泄漏 : http : //connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory -泄漏

但遗憾的是我没有找到任何解决方案。 既然很久以前就已经问过这个问题,那么我想问一下它是否已经解决了?

非常感谢。

更新:

似乎在我切换到使用SAPI COM dll而不是.Net Speech.Synthesizer包时(虽然基本上它们是相同的东西),内存停止泄漏。

为什么两个调用行为(SAPI dll vs .net Speech package)具有不同的内存行为? 因为后者似乎只是前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(); } 

}

内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

说到……内存:32044 KB

我不确定SpeechSynthesizer的所有细节,但你可以尝试在这里使用一次性模式。 因为SpeechSynthesizer实现了IDisposable

您的代码如下所示:

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

如果你注意到这与微软的例子Here非常相似

这看起来实际上是内存泄漏,您是否尝试过使用Microsoft.Speech运行时 ? 语法看起来非常相似,他们提到它不应该有相同的问题。

最终解决方案

谷歌相关的关键词告诉我,这实际上是微软的一个错误。

似乎在我切换到使用SAPI COM dll而不是.Net Speech.Synthesizer包时(虽然基本上它们是相同的东西),内存停止泄漏。

我知道这是一个旧线程,但还有另一种解决方案。 使用Microsoft.Speech.Synthesis.SpeechSynthesizer而不是System.Speech.Synthesis.SpeechSynthesizer

Microsoft.Speech.Synthesis.SpeechSynthesizer包含在Microsoft语音平台 – 软件开发工具包(SDK)(版本11)中https://www.microsoft.com/en-us/download/details.aspx?id=27226

此版本的Synthesizer没有内存泄漏。