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

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-leak

但不幸的是,我没有找到任何解决方法。由于这个问题已经很久以前就被问过了,所以我想问一下它是否已经被解决了?

非常感谢。

更新:

似乎当我切换到使用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

3个回答

4

最终解决方案:

通过谷歌相关关键词得知这其实是微软的一个bug。

似乎当我使用SAPI COM dll而非.Net Speech.Synthesizer包时(虽然它们本质上是相同的东西),内存泄漏就停止了。


你能发布其中任何一个链接吗?这个问题是否有MS Connect的问题报告? - codekaizen
@codekaizen 是的,实际上我在微软论坛上读到了一些用户的报告,这篇帖子是两年前发布的。这就是为什么我得出这样的结论。我需要再次搜索我上个月实际阅读的帖子... - JXITC

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.Speech运行时?语法看起来非常相似,他们已经提到它不应该有同样的问题。

1
谢谢 :) 但它仍然存在内存泄漏问题。 - JXITC
根据微软自己的承认,这确实是一个泄漏问题。请参见上面的编辑。 - Kyle C
为什么两种调用行为(SAPI dll vs .net Speech package)具有不同的内存行为?因为后者似乎只是前者SAPI dll的包装器。 - JXITC
我不确定,我是根据微软代表在这里说的内容:http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak。 - Kyle C

1
我知道这是一个旧的主题,但是还有另一种解决方案来解决这个问题。使用Microsoft.Speech.Synthesis.SpeechSynthesizer代替System.Speech.Synthesis.SpeechSynthesizerMicrosoft.Speech.Synthesis.SpeechSynthesizer包含在Microsoft Speech Platform - Software Development Kit (SDK) (Version 11)中 - https://www.microsoft.com/en-us/download/details.aspx?id=27226 这个版本的合成器没有内存泄漏问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接