2010-02-04 16 views
8

मैंने एक प्रोजेक्ट विकसित किया है जिसे मैं रिलीज़ करना चाहता हूं जो सी #, डब्ल्यूपीएफ और सिस्टम स्पीच। सिंथेसाइज़र ऑब्जेक्ट का उपयोग करता है। इस परियोजना की रिहाई को रोकने वाली समस्या यह है कि जब भी SpeakAsync कहा जाता है तो यह एक स्मृति रिसाव छोड़ देता है जो अंतिम विफलता के बिंदु तक बढ़ता है। मेरा मानना ​​है कि मैंने इस ऑब्जेक्ट का उपयोग करने के बाद ठीक से साफ किया है, लेकिन इलाज नहीं मिल रहा है। मैंने एंट्स मेमोरी प्रोफाइलर के माध्यम से प्रोग्राम चलाया है और यह रिपोर्ट करता है कि प्रत्येक कॉल के साथ WAVEHDR और WaveHeader बढ़ रहा है।स्पीचसिंथेसाइज़र में लगातार मेमोरी लीक

मैंने कारण को इंगित करने के लिए एक नमूना प्रोजेक्ट बनाया है, लेकिन अभी भी नुकसान में है। किसी भी सहायता की सराहना की जाएगी।

प्रोजेक्ट VS2008 का उपयोग करता है और एक सी # डब्ल्यूपीएफ प्रोजेक्ट है जो .NET 3.5 और किसी भी CPU को लक्षित करता है। आपको System.Speech को मैन्युअल रूप से संदर्भ जोड़ने की आवश्यकता है।

यहाँ कोड है:

<Window x:Class="SpeechTest.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Grid> 
    <StackPanel Orientation="Vertical"> 

     <Button Content="Start Speaking" Click="Start_Click" Margin="10" /> 
     <Button Content="Stop Speaking" Click="Stop_Click" Margin="10" /> 
     <Button Content="Exit" Click="Exit_Click" Margin="10"/> 

    </StackPanel> 
</Grid> 



// Start of code behind 
using System; 
using System.Windows; 
using System.Speech.Synthesis; 

namespace SpeechTest 
{ 
    public partial class Window1 : Window 
    { 

     // speak setting 
     private bool speakingOn = false; 
     private int curLine = 0; 
     private string [] speakLines = { 
      "I am wondering", 
      "Why whenever Speech is called", 
      "A memory leak occurs", 
      "If you run this long enough", 
      "It will eventually crash", 
      "Any help would be appreciated" }; 

     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void Start_Click(object sender, RoutedEventArgs e) 
     { 
      speakingOn = true; 
      SpeakLine(); 
     } 

     private void Stop_Click(object sender, RoutedEventArgs e) 
     { 
      speakingOn = false; 
     } 

     private void Exit_Click(object sender, RoutedEventArgs e) 
     { 
      App.Current.Shutdown(); 
     } 

     private void SpeakLine() 
     { 
      if (speakingOn) 
      { 
       // Create our speak object 
       SpeechSynthesizer spk = new SpeechSynthesizer(); 
       spk.SpeakCompleted += new EventHandler(spk_Completed); 
       // Speak the line 
       spk.SpeakAsync(speakLines[curLine]); 
      } 
     } 

     public void spk_Completed(object sender, SpeakCompletedEventArgs e) 
     { 
      if (sender is SpeechSynthesizer) 
      { 

       // get access to our Speech object 
       SpeechSynthesizer spk = (SpeechSynthesizer)sender; 
       // Clean up after speaking (thinking the event handler is causing the memory leak) 
       spk.SpeakCompleted -= new EventHandler(spk_Completed); 
       // Dispose the speech object 
       spk.Dispose(); 
       // bump it 
       curLine++; 
       // check validity 
       if (curLine >= speakLines.Length) 
       { 
        // back to the beginning 
        curLine = 0; 
       } 
       // Speak line 
       SpeakLine(); 
      } 
     } 
    } 
} 




मैं Windows 7 64 बिट इस कार्यक्रम चलाने के लिए और इसे चलाने और अंततः को रोकने जब एक नया SpeechSynthesizer वस्तु बनाने के लिए प्रयास करते हैं। जब Windows Vista 64 बिट पर चलते हैं तो स्मृति 34k से शुरुआती बिंदु से लगभग 400k तक बढ़ती है और बढ़ती जा रही है।

क्या कोई भी उस कोड में कुछ भी देख सकता है जो इसका कारण हो सकता है, या यह स्पीच ऑब्जेक्ट के साथ कोई समस्या है।

किसी भी मदद की सराहना की जाएगी।

+0

आप यकीन है कि यह लगातार ऊपर जा रहा रखता है? स्मृति तब तक जारी रहेगी जब तक जीसी आती है और चीज़ों को साफ नहीं करती है। जब तक यह लगातार ऊपर नहीं जाता और कभी नीचे नहीं आता है, तो मैं इसके बारे में चिंता नहीं करता। –

+0

हाँ, जब मैं इस विंडोज 7 पर चलने यह अंततः जब एक नया SpeechSynthesizer वस्तु बनाने के प्रयास को रोकने जाएगा। कार्यक्रम के बाद, पैनल को नियंत्रित करने और टेक्स्ट-टू-स्पीच का परीक्षण करने का प्रयास करने के परिणामस्वरूप इसका परिणाम होगा। जब तक मशीन पुनरारंभ नहीं हो जाती तब तक यह बात नहीं करेगी। – DudeFX

+0

अगर आप प्रत्येक पारित पर एक नया SpeechSynthesizer वस्तु बनाने नहीं है क्या होता है? –

उत्तर

3

मैं इस अवलोकन की पुष्टि कर सकता हूं। मैं अपने बालों को खींच रहा था, जहां मेरा प्रोग्राम लीक हो रहा था और यह है। System.speech

में मैंने एक ऐप परिवर्तित कर दिया है जो मैंने नई प्रणाली का उपयोग करने के लिए COM- आधारित स्पीच ऑब्जेक्ट्स का उपयोग किया है। स्पीच नेट 3.5 में नेट लाइब्रेरी। .Net ऐप के भीतर सभी मैंग किए गए कोड का उपयोग करने के लिए आगे बढ़ने के सही तरीके की तरह लग रहा था। ऐप अचानक एक छोटा मेम रिसाव था।

मैंने इसे दो सरल ऐप्स में तोड़ दिया जो बोले गए शब्दों की डब्ल्यूएवी फ़ाइल में "यह एक परीक्षण है" को परिवर्तित करता है। एक COM- आधारित भाषण ऑब्जेक्ट्स का उपयोग करता है, दूसरा सिस्टम.Speech का उपयोग करता है। मैंने उन्हें 24 घंटे तक चलाया, प्रत्येक डब्ल्यूएवी को 200,000 बार बना रहा।

COM आधारित भाषण ऑब्जेक्ट्स: कोई मेम रिसाव नहीं। लगभग 40 मिनट

सिस्टम.speech: धीमी रिसाव, अच्छी और रैखिक के बाद 13 एमबी पर ऐप का मेम उपयोग शीर्ष पर पहुंच गया। 24 घंटे

+0

धन्यवाद! असल में आपका जवाब एकमात्र सही है! – JXITC

+0

मैं भी रिसाव में आया हूं और अब आपके संकेत से हल हो गया है। – JXITC

2

SendAsync()Ping से लगभग 14 एमबी से 45 एमबी तक रैंक भी लीक। प्रेषक को IDisposable पहले के रूप में डालने का समाधान है। तो शायद निम्नलिखित भी काम करता है।

((IDisposable)spk).Dispose(); 
0

मैं अपने प्रश्न के लिए एक बहुत ही सरल जवाब दे सकते हैं: SpeechSynthesizer स्थिर बनाने !!!

मैं काफी यकीन है कि यह आपकी समस्या का समाधान होगा।

इसके अलावा - एक टिप == >> हर बार जब आप कोड, और आप एक संसाधन है ... का उपयोग के रूप में स्थिर और अपने जीवन बेहतर होगा!

+0

मुझे नहीं लगता कि उदाहरण थ्रेड सुरक्षित हैं, आपको कई धागे में एक स्थिर स्पीच सिंथेसाइज़र उदाहरण का उपयोग करने में समस्याएं मिलेंगी। – Nariman

संबंधित मुद्दे