首页 新闻 会员 周边 捐助

求助使用SpeechSynthesizer发生内存泄露问题(难道是微软的一个bug)

0
悬赏园豆:200 [待解决问题]

在使用SpeechSynthesizer时候使用简单代码,程序大概如下

using (SpeechSynthesizer synth = new SpeechSynthesizer())
{

// Configure the audio output.
synth.SetOutputToDefaultAudioDevice();

// Speak a string synchronously.
synth.Speak(“你好”);
}

程序每次调用完后,自动释放资源,但是调用平凡发现每次,使用完后虽然程序使用内存虽然能够释放,但是下次在调用该函数的时候,程序就会恢复到以前的内存占用值,并增加使用新的内存,知道占用内存过多程序崩溃。看到有人深入分析过,这个问题,最后得到的结论是无解,不知道哪位大师遇到过这个问题,求解。

骨感烟灰哥的主页 骨感烟灰哥 | 初学一级 | 园豆:2
提问于:2014-10-05 00:34
< >
分享
所有回答(5)
0

.NET内存释放是不可控的,天知道什么时候释放

56180825 | 园豆:1749 (小虾三级) | 2014-10-05 10:35
0

研究了一下你说的这个问题,发现确实如你所说:

1、当第一次启动Speach的时候,会有一个猛的内存增长,大概有4M+,这个应该是启动Speach的时候的基础功能代码与数据占用的内存空间

2、每次调用Speak后,都会有小几百K的内存增长,也可能更多(跟要输出的文字内容长短有关),这个应该是文字内容合成为语音内容所占用的内存空间

3、每次重复Speak,都会有大致相差不大的内存空间增长。

分析:

1、这个是没办法的,我想也应该能接受,不管是几M还是多少,好在是固化的大小

2、这个,应该也能接受吧?文字内容合成为语音内容,数据总要占用空间。

3、至于这个,是没办法的,我检查了语音的相关配置,没有把合成语音重复使用的示例,如果可以的话,我想对于重复的内容是可以进行缓存的。尝试使用Prompt,但是这个只能使用一次,也就失去了价值。

问题的解决其实很简单,.net的垃圾回收机制你应该知道,垃圾回收并非在你把对象处置后就会立即回收的,除非你强制执行,当你把一个程序放置久了后,你会发现,内存是会降下来的。

519740105 | 园豆:5810 (大侠五级) | 2014-10-05 10:36

我的软件,播放需要不停得播放语音,几天过后内存不停增长直到报错,语音播放方法,出现该异常

Error:System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

应该是说

支持(0) 反对(0) 骨感烟灰哥 | 园豆:2 (初学一级) | 2014-10-06 23:07

@骨感烟灰哥: 你这个问题还真的无能为力,给你几个建议:

1、试着使用异步播放?speakasync,同时通过completed事件来实现对象的处置。

2、.net自带的语音合成原则上只是为了满足一些小型的需求,象你这样的,应该属于专业需求了,看是否可以找第三方软件实现。

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2014-10-07 07:43
0

之前试过,如果对于每几秒发生一次的事件,采用USING方式连接数据库,也是会让内存占用不停上升。

所以对于这类非常规应用,建议有必要考虑是否采用类似连接池方式。

如果不能开多个连接的话,或者使用资源多线程锁定方式,来避免NET释放内存太慢的问题。

爱编程的大叔 | 园豆:30844 (高人七级) | 2014-10-05 18:29
0

一个治标不治本的办法,手动GC:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

jello chen | 园豆:7336 (大侠五级) | 2014-10-05 20:36

这个貌似对于语音不起作用

支持(0) 反对(0) 骨感烟灰哥 | 园豆:2 (初学一级) | 2014-10-06 23:08
0

楼上的加上synth =null,垃圾回收不是实时的,想办法自己释放呗,具体代码,怎么释放不是问题吧

draculav | 园豆:734 (小虾三级) | 2014-10-09 13:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册