Утечка памяти в .Net Speech.Synthesizer?

Я обнаружил постоянную утечку в своем приложении. Изучив с помощью профилировщика памяти, я обнаружил, что в ход идет какой-то объект от 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 КБ

Говоря... Память: 42312 КБ

Говоря... Память: 42440 КБ

Говоря... Память: 42568 КБ

Говоря... Память: 42696 КБ

Говоря... Память: 42824 КБ

Говоря... Память: 43016 КБ

Говоря... Память: 43372 КБ

Я погуглил и обнаружил, что многие другие сталкивались с той же проблемой: 1: Постоянная утечка памяти в SpeechSynthesizer 2: http://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak

но, к сожалению, я не нашел никакого решения для этого. Поскольку проблема уже задана давно, поэтому я хочу спросить, решена она или нет?

Огромное спасибо.

ОБНОВЛЕНИЕ:

Похоже, пока я переключаюсь на использование dll SAPI COM, а не пакета .Net Speech.Synthesizer (хотя по сути это одно и то же), память перестает течь.

Почему поведение двух вызовов (библиотека SAPI dll и пакет .net Speech) имеет разное поведение памяти? Поскольку последний кажется просто оболочкой для прежней dll SAPI.

    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 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ

Говоря... Память: 32044 КБ


person JXITC    schedule 22.05.2012    source источник


Ответы (3)


Окончательное решение:

Поиск в Google релевантных ключевых слов говорит мне, что на самом деле это ошибка Microsoft.

Похоже, пока я переключаюсь на использование dll SAPI COM, а не пакета .Net Speech.Synthesizer (хотя по сути это одно и то же), память перестает течь.

person JXITC    schedule 26.06.2012
comment
Можете ли вы опубликовать любую из этих ссылок? Есть ли для него проблема с MS Connect? - person codekaizen; 27.06.2012
comment
@codekaizen Да, на самом деле я прочитал отчет некоторых пользователей на форуме MS, пост был опубликован два года назад. Вот почему я прихожу к такому выводу. Мне нужно будет снова поискать пост, который я действительно читал в прошлом месяце... - person JXITC; 27.06.2012

Я не знаю всех подробностей о 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 здесь

На самом деле это похоже на утечку памяти. Пробовали ли вы использовать Среда выполнения Microsoft.Speech? Синтаксис выглядит очень похоже, и они упомянули, что он не должен иметь ту же проблему.

person Kyle C    schedule 22.05.2012
comment
Спасибо :) но у него все еще есть утечки памяти - person JXITC; 22.05.2012
comment
Судя по собственному признанию Microsoft, это выглядит так. См. Редактировать выше. - person Kyle C; 22.05.2012
comment
Почему два поведения вызова (SAPI dll и .net Speech package) имеют разное поведение памяти? Поскольку последний кажется просто оболочкой для прежней dll SAPI. - person JXITC; 22.05.2012
comment
Я не уверен, я исхожу из того, что сказал здесь представитель Microsoft: connect.microsoft.com/VisualStudio/feedback/details/664196/ - person Kyle C; 22.05.2012

Я знаю, что это старая тема, но есть другое решение проблемы. Используйте Microsoft.Speech.Synthesis.SpeechSynthesizer вместо System.Speech.Synthesis.SpeechSynthesizer.

Microsoft.Speech.Synthesis.SpeechSynthesizer входит в состав Microsoft Speech Platform — Software Development Kit (SDK) (версия 11)https://www.microsoft.com/en-us/download/details.aspx?id=27226

Эта версия синтезатора не имеет утечки памяти.

person Roman Lumetsberger    schedule 08.05.2018