2011-08-18 10 views
9

RPM Heap CompareHttpRequest/HttpResponse मेमोरी लीक? CF.NET 3.5 विन सीई 6,0

मैं मैं क्या सोचता CF.NET 3.5 में HttpRequest या HttpResponse कक्षा एक जीत CE 6.0 डिवाइस पर चल साथ एक स्मृति रिसाव है से छुटकारा पाने के लिए हर संभव कोशिश की है। मैं उन्हें आईपी कैमरा के साथ संवाद करने के लिए उपयोग कर रहा हूं।

नीचे वर्तमान कोड है जिसका उपयोग मैं कर रहा हूं। कोड थ्रेड पर कस्टम नियंत्रण में चल रहा है, इसकी प्राथमिकता सामान्य से नीचे और पृष्ठभूमि कार्यकर्ता को सही पर सेट किया गया है। मेरे दो रूपों में से इनमें से दो नियंत्रण वस्तुएं हैं।

मैं वर्तमान कहते हैं क्योंकि मैं async अनुरोध और स्मृति की खपत में कोई कमी नहीं के साथ नीचे दिए गए कोड के अन्य क्रमपरिवर्तन की कोशिश की है:

protected void CamRefreshThread() 
    { 
     while (true) 
     { 
      if (false != CamEnabled) 
      { 
       HttpWebRequest HttpReq = null; 

       try 
       { 
        lock (LockObject) 
        { 
         // create request 
         HttpReq = (HttpWebRequest)WebRequest.Create("http://" + this.Ipv4Address + "/axis-cgi/jpg/image.cgi"); 
         HttpReq.Timeout = 5000; 
         HttpReq.ReadWriteTimeout = 5000; 
         HttpReq.Credentials = new NetworkCredential(this.CamUserName, this.CamPassword); 
        } 

        /* indicate waiting for reponse */ 
        ResponseRxed = false; 
        // get response 
        using (HttpWebResponse HttpResp = (HttpWebResponse)HttpReq.GetResponse()) 
        { 
         // get response streamImageFromStream 
         using (Stream ImgStream = HttpResp.GetResponseStream()) 
         { 
          // get bitmap 
          using (Bitmap ImgFrmStream = new Bitmap(ImgStream)) 
          { 
           if (false != CamEnabled) 
           { 
            /* indicate response has not timed out */ 
            ResponseTimedOut = false; 
            ResponseFirst = true; 
            // marshall bitmap 
            this.Invoke(GetBitmapDelegate, ImgFrmStream); 
            /* indicate response rxed */ 
            ResponseRxed = true; 
           } 
          } 
         } 
        } 
       } 
       catch (WebException e) 
       { 
        if (false == ResponseTimedOut) 
        { 
         ResponseTimedOut = true; 
         ResponseFirst = false; 
         this.Invoke(RefreshDisplayDelegate); 
        } 
       } 
       catch (Exception) 
       { 

       } 
       finally 
       { 
        if (null != HttpReq) 
        { 
         HttpReq.Abort(); 
        } 
       } 
      } 

      Thread.Sleep(1); 
     } 
    } 

मैं आरपीएम के साथ और स्मृति बढ़ता है के रूप में यह प्रोफाइल है, इसलिए एक कर System.Net नेमस्पेस और सिस्टम के लिए रूट ऑब्जेक्ट्स का बेंच। नामस्थान को पढ़ना, जिसमें धागे का एक गुच्छा और सिंक ऑब्जेक्ट्स शामिल हैं जिन्हें मैं नहीं बना रहा हूं।

मैंने पहले और आखिरी ढेर स्नैपशॉट की ढेर तुलना की एक छवि संलग्न की है।

मैंने "उपयोग" का उपयोग करना सुनिश्चित किया है और सभी ऑजेक्ट्स पर निपटान करने की अनुमति दी है जो इसे अनुमति देते हैं। साथ ही, मैं पूरा होने पर अनुरोध को रद्द करना सुनिश्चित करता हूं। मैंने इसे अन्य उदाहरणों में देखा है और यह कनेक्शन संसाधनों को जारी करना है, आदि

यहां अजीब हिस्सा है, रिसाव केवल तब होता है जब टाइमआउट वेबएक्सप्शन फेंक दिया जाता है यदि मेरे पास कैमरे जुड़े नहीं हैं। कैमरे से जुड़े हुए, डिवाइस स्मृति में वृद्धि के बिना दिनों तक चलता है। साथ ही, बाइट्स की प्रबंधित संख्या और बाइट्स की कुल संख्या आरपीएम में बढ़ती है, इसलिए मुझे नहीं लगता कि यह एक असंगत रिसाव है। आखिरकार, मैं जितनी जल्दी हो सके कैमरे से छवियां प्राप्त करने का प्रयास कर रहा हूं। मुझे आश्चर्य है कि मैं सिर्फ जीसी समय इकट्ठा करने के लिए नहीं दे रहा हूं। लेकिन जब एक संग्रह होता है (मुझे लगता है कि संग्रह गणना आरपीएम में बढ़ती है) प्रबंधित बाइट गिनती नीचे नहीं जाती है, यह सिर्फ बढ़ती रहती है। उम्मीद है कि मैं कुछ बेवकूफ कर रहा हूं और यह एक आसान फिक्स है। हमेशा की तरह, किसी भी मदद या सुझाव की सराहना की जाती है।

अतिरिक्त जानकारी:

दो प्रतिनिधियों कैमरा धागे से लागू के रूप में इस प्रकार है अगर यह पता करने के लिए मदद कर सकता है कर रहे हैं:

GetBitmapDelegate = new VoidDelegateBitmap(UpdateCamImage); 
RefreshDisplayDelegate = new VoidDelegateVoid(RefreshCamImage); 

protected void UpdateCamImage(Bitmap Frame) 
{ 
    if (null != BmpOffscreen) 
    { 
     BmpOffscreen.Dispose(); 
    } 

    BmpOffscreen = (Bitmap)Frame.Clone(); 
    Refresh(); 
} 

protected void RefreshCamImage() 
{ 
    Refresh(); 
} 

अतिरिक्त INFO2:

बस जानकारी के लिए, नीचे पूरा करने के लिए मैंने ऑनपेंट() इत्यादि शामिल किया है। मैं कैमरे के लिए स्क्रीन पर बिटमैप पेंट करता था:

protected override void OnPaint(PaintEventArgs e) 
{ 
    string DisplayString = null; 

    if (false == CamEnabled) 
    { 
     DisplayString = string.Empty; 
    } 
    else if (false != ResponseTimedOut) 
    { 
     DisplayString = "Communication Timeout!"; 
    } 
    else if ((null != BmpOffscreen) && (false != ResponseFirst)) 
    { 
     e.Graphics.DrawImage(BmpOffscreen, 0, 0); 
    } 
    else 
    { 
     DisplayString = "Loading..."; 
    } 

    if (null != DisplayString) 
    { 
     e.Graphics.Clear(this.BackColor); 

     using (SolidBrush StringBrush = new SolidBrush(this.ForeColor)) 
     { 
      using (StringFormat Format = new StringFormat()) 
      { 
       Format.LineAlignment = StringAlignment.Center; 
       Format.Alignment = StringAlignment.Center; 
       e.Graphics.DrawString(DisplayString, this.Font, StringBrush, this.ClientRectangle, Format); 
      } 
     } 
    } 
} 

protected override void OnPaintBackground(PaintEventArgs e) 
{ 

} 

अद्यतन:

यहां मुझे जो नहीं मिलता है। चूंकि HttpRequest केवल एक ऑब्जेक्ट है जो जानकारी रखता है और उसे बंद/डिस्पोजेड नहीं किया जा सकता है, और जब से टाइमआउट वेबएक्सप्शन फेंक दिया जाता है, तो HttpResponse अभी भी शून्य है (बंद नहीं किया जा सकता है), अनुरोध का प्रयास करने के लिए उपयोग किए जाने वाले संसाधनों का संदर्भ क्या है? एकमात्र व्याख्या यह है कि HttpRequest ऑब्जेक्ट द्वारा आयोजित कुछ संदर्भ हैं कि जब एबॉर्ट कहा जाता है, तो अनुरोध करने के लिए उपयोग किए जाने वाले संसाधनों को छोड़ना चाहिए, जिन्हें मैं आरपीएम में पुनर्प्राप्त नहीं कर रहा हूं। चूंकि मैं एबॉर्ट() को कॉल करता हूं और चूंकि एचटीपीआरक्वेट ऑब्जेक्ट केवल अनुरोध के दौरान दायरे में है, इसलिए मुझे नहीं लगता कि किसी भी संसाधन का संदर्भ कैसे एकत्र नहीं किया जा सकता है।

Update2:

ठीक है, मैं, यह कैमरों को सक्षम करने पर चलाते हैं और समय समाप्ति जारी रखने की अनुमति तो मैं कैमरे अक्षम, HttpRequest प्रयास और समय समाप्ति को नष्ट करने, और यह दिन के बाकी चलाते हैं । दिन के अंत में, जीसी एक ही मूल्य पर अटक गया था (पिछले परीक्षण के आधार पर इसे लगभग 6 एमबी तक उगाया जाना चाहिए), साबित करना कि जीसी समय इकट्ठा करने के लिए कुछ भी नहीं है, कम से कम मुझे लगता है। तो संसाधन अभी भी लिम्बो में बंद हैं और मुझे यह पता लगाने की ज़रूरत है कि उन्हें क्या जड़ रखा जा रहा है। उम्मीद है कि मैं को समझ सकता हूं और एक और अपडेट दे सकता हूं। तब तक ...

साइड नोट:

क्या कभी किसी ने HttpRequest/HttpResponse, इस्तेमाल किया गया है एक विन सीई डिवाइस CF.NET 3.5 का उपयोग करने पर एक आईपी कैमरे से चित्र प्राप्त करने के? यदि हां, तो कैमरे से कॉम के नुकसान के लिए अनिश्चित अवधि के लिए एक टेस्ट केस था? यह पहली बात थी जो मैंने पूछा था क्योंकि मुझे एम्बेडेड डिवाइस से आईपी कैमरों से संवाद करने के तरीके के बारे में बहुत सारे उदाहरण नहीं मिल पाए हैं।

Update3:

खैर मुझे लगता है कि मैं अपने विशिष्ट समस्या के लिए एक ठीक पर ठोकर खाई है। मैं डिफ़ॉल्ट कनेक्शन की संख्या और अधिकतम निष्क्रिय समय के संबंध में ServicePointManager स्थिर वर्ग के सदस्यों को कुछ बदलाव किए हैं:

ServicePointManager.DefaultConnectionLimit = 4; 
ServicePointManager.MaxServicePointIdleTime = 1000; 

जब से मैं 4 कैमरों किसी भी समय जुड़ा हुआ की एक अधिकतम होगा, और मेरे समय समाप्ति के बाद से HttpRequest के लिए 5000ms पर सेट है, मुझे लगा कि मैं खुश होने के लिए 1000ms अधिकतम निष्क्रिय समय का प्रयास करूंगा। मैंने रात में दो इकाइयों को बिना कैमरे से जुड़े (हर 5000 एमएमएस का समय निकाल दिया) चलाया। आम तौर पर ऐसा होता है कि मैं सुबह आउंगा और डिवाइस ओओएम संदेश के साथ वहां बैठे होंगे और जीसी मेमोरी और भौतिक मेमोरी मेरे सिस्टम के लिए अधिकतम हो जाएगी। खैर, दोनों डिवाइस एक ही स्मृति स्तर पर थे कि जब मैं कल रात छोड़ दिया था। तो, मुझे आशा है कि यह मेरे मुद्दे के लिए ठीक है। एमएसडीएन दस्तावेज के आधार पर:

कनेक्शन लिमिट संपत्ति अधिकतम सेवा कनेक्शन सेट करती है जो सर्विसपॉइंट इंटरनेट संसाधन में कर सकती है। ConnectionLimit प्रॉपर्टी का मान ServicePointManager.DefaultConnectionLimit प्रॉपर्टी के मान पर सेट किया गया है जब सर्विसपॉइंट बनाया गया है; DefaultConnectionLimit में बाद में परिवर्तन मौजूदा सर्विसपॉइंट उदाहरणों पर कोई प्रभाव नहीं पड़ता है।

मैक्सआईडलटाइम संपत्ति में मिलीसेकंड में समय की लंबाई शामिल है, कि सर्विसपॉइंट को किसी अन्य कनेक्शन में उपयोग के लिए पुनर्नवीनीकरण करने से पहले इंटरनेट संसाधन से निष्क्रिय कनेक्शन बनाए रखने की अनुमति है। आप MaxIdleTime को टाइमआउट पर सेट कर सकते हैं। यह इंगित करने के लिए अनंत है कि सर्विसपॉइंट को कभी भी टाइमआउट नहीं करना चाहिए। MaxIdleTime प्रॉपर्टी का डिफ़ॉल्ट मान ServicePointManager.MaxServicePointIdleTime प्रॉपर्टी का मान है जब सर्विसपॉइंट बनाया गया है। MaxServicePointIdleTime प्रॉपर्टी के बाद के परिवर्तनों का मौजूदा सर्विसपॉइंट उदाहरणों पर कोई प्रभाव नहीं पड़ता है।

MaxServicePointIdleTime प्रॉपर्टी अधिकतम निष्क्रिय समय सेट करती है जो ServicePointManager सर्विसपॉइंट उदाहरण बनाते समय MaxIdleTime प्रॉपर्टी को असाइन करता है। इस मान में परिवर्तन केवल सेवापॉइंट उदाहरणों को प्रभावित करेंगे जो मूल्य बदलने के बाद प्रारंभ किए गए हैं। MaxIdleTime में निर्दिष्ट समय के लिए सर्विसपॉइंट निष्क्रिय होने के बाद, यह कचरा संग्रह के लिए योग्य है। सर्विसपॉइंट से जुड़े कनेक्शन की सूची खाली होने पर एक सर्विसपॉइंट निष्क्रिय है।

मेरे लिए यह सब कुंजी यह है कि विशेष रूप से कहा गया है कि सेवा बिंदु के बाद अधिकतम निष्क्रिय समय के लिए निष्क्रिय है यह कचरा संग्रह के लिए योग्य है।मैंने इस मूल्य के लिए डिफ़ॉल्ट रूप से 100 सेकंड से 900 सेकेंड तक कहीं भी देखा है, विवरण के आधारभूत ढांचे संस्करण के आधार पर। इससे पहले कि मैं इसे ठीक करता हूं, मैं कुछ और परीक्षण करने जा रहा हूं। मैं यहां उन लोगों से प्यार करूंगा जिन्होंने इन विशिष्टताओं को अपने विशिष्ट मुद्दों को ठीक करने के लिए खेला है और क्या यह समस्या को देखते हुए समस्या के मूल कारण के रूप में समझ में आता है या नहीं। सभी प्रतिक्रियाओं की सराहना की जाती है। अग्रिम में धन्यवाद।

+0

'RefreshDisplayDelegate' में क्या हो रहा है? – ctacke

+0

रीफ्रेश डिस्प्ले एक विधि को इंगित करें जो एक टाइमआउट होने पर नियंत्रण पर ताज़ा करें() को कॉल करता है। मैं बिटमैप पर एक स्ट्रिंग खींचता हूं जिसमें कहा गया है कि कैमरा कॉम खो गया है। मैंने मूल प्रतिनिधियों में दो प्रतिनिधियों के साथ जोड़ा है जो मैंने धागे से आह्वान किया था। जवाब के लिए धन्यवाद। – CCS

उत्तर

1

कृपया पोस्ट में Update3 को देखें। ऐसा लगता है कि सूचीबद्ध कारणों से मेरी समस्या ठीक हो गई है। प्रतिक्रियाओं के लिए धन्यवाद।

1

पूरी तरह गलत करने के लिए अपने HttpWebRequest वस्तु की AllowWriteStreamBuffering गुण सेट:

HttpReq.AllowWriteStreamBuffering = false; 
HttpReq.AllowAutoRedirect = false; 
+0

कॉम्पैक्ट फ्रेमवर्क में, AllowWriteStreamBuffering को गलत पर डिफॉल्ट किया गया है, लेकिन AllowAutoRedirect नहीं है। मुझे इसे एक मौका और देना होगा। मैंने यह भी देखा कि KeepAlive ध्वज को सही करने के लिए डिफ़ॉल्ट किया गया है। एक समय में मेरे पास AllowWriteStreamBuffering और KeepAlive दोनों स्पष्ट रूप से झूठे सेट किए गए थे और इसमें कोई फर्क नहीं पड़ता था। मैं उन्हें सभी को गलत कर दूंगा और देख सकता हूं कि यह कैसा प्रदर्शन करता है। जवाब के लिए धन्यवाद। – CCS

+0

हाँ, इससे कोई फर्क नहीं पड़ता। फिर भी धन्यवाद। – CCS

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