8

我在我的应用程序中发现了一个持续的泄漏。在使用内存分析器检查后,我发现课程是来自 Microsoft Speech.Synthesizer 的一些对象

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

//显示 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

我用谷歌搜索了它,发现许多其他人也遇到了同样的问题: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 包)有不同的内存行为?后者似乎只是前一个 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

4

3 回答 3

4

最终解决方案:

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

似乎当我切换到使用 SAPI COM dll 而不是 .Net Speech.Synthesizer 包时(尽管它们本质上是相同的),内存停止泄漏。

于 2012-06-26T21:01:12.800 回答
3

我不确定 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"));
   }
}

如果您注意到这与 Microsoft 的示例非常相似Here

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

于 2012-05-22T18:15:23.440 回答
1

我知道这是一个旧线程,但该问题还有另一种解决方案。使用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

此版本的合成器没有内存泄漏。

于 2018-05-08T08:51:42.480 回答