2012-05-22 39 views
7

我在我的應用程序中發現連續泄漏。使用內存分析器檢查後,我發現課程是某個對象從微軟Speech.Synthesizer.Net 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: Constant Memory Leak in SpeechSynthesizer 2: http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak

但遺憾的是我沒有找到任何解決方案。既然它早已問過一個問題,所以我想問一下它是否被解決了?

很多謝謝。

UPDATE:

好像當我切換使用SAPI的COM DLL而不是淨Speech.Synthesizer包(雖然本質上它們是一回事),內存泄漏停止。

爲什麼兩個調用行爲(SAPI dll vs .net語言包)有不同的內存行爲?因爲後者似乎只是前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

最終的解決方案:

谷歌,荷蘭國際集團相關的關鍵字,告訴我,它實際上是從微軟的錯誤。

好像而我切換使用SAPI COM DLL而不是淨Speech.Synthesizer包(雖然實質上它們是相同的東西),則存儲器停止泄漏。

+0

你可以發佈任何這些鏈接?是否有MS Connect問題? – codekaizen

+0

@codekaizen是的,其實我在MS論壇看過一些用戶報道,這個帖子是兩年前發佈的。這就是我得出這個結論的原因。我將需要再次搜索我上個月實際閱讀的帖子...... – 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")); 
    } 
} 

如果你發現這是非常類似於微軟的例子Here

這看起來其實是一種內存泄漏,你有沒有嘗試使用Microsoft.Speech runtime? 的語法看起來非常相似,他們都提到不應有同樣的問題。

+1

謝謝:)但它仍然有內存泄漏 – JXITC

+0

它看起來那麼基於微軟自己也承認這種泄漏。請參閱上述編輯。 –

+0

爲什麼兩個調用行爲(SAPI DLL VS .NET語音包)有不同的內存的行爲呢?因爲後者似乎只是前SAPI DLL的包裝。 – JXITC