2011-05-27 11 views
7

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

समस्या यह हो सकती है कि Google Instant किसी भी तरह से पिछले पृष्ठों से डेटा रख रहा है, लेकिन जब मैं कहीं और नेविगेट करता हूं, जैसे "लगभग: खाली", स्मृति का उपयोग घट जाएगा नहीं। यह समस्या भी मैं अपने स्मृति पेज 60 पर इस्तेमाल किया नीचे लेखन शुरू आईई 9 के साथ होता है और यह है कि क्या मैं (आईई 9) के साथ मिल गया है:

Page 60: 180 MB 
Page 70: 214 MB 
Page 80: 245 MB 
Page 90: 280 MB 

तो जैसा कि आप देख सकते हैं, स्मृति लगभग 30 से lineally बढ़ जाती है - हर 10 पृष्ठों में 35 एमबी। Google से दूर नेविगेट करने के बाद स्मृति जारी होने पर यह कोई समस्या नहीं होगी। लेकिन नहीं है।

मैंने this भी कोशिश की और कुछ भी नहीं किया।

संपादित करें: मैंने इसका परीक्षण करने के लिए एक प्रोजेक्ट बनाया है। यहाँ मेरी Form1 कोड है:

namespace WebBrowserMemoryTest 
{ 
    public partial class Form1 : Form 
    { 
     private int _Pages; 

     public Form1() 
     { 
      InitializeComponent(); 
      webBrowser1.Navigate("http://www.google.com"); 
     } 

     private void startButton_Click(object sender, EventArgs e) 
     { 
      _Pages = 0; 
      timer1.Start(); 
     } 

     private void stopButton_Click(object sender, EventArgs e) 
     { 
      timer1.Stop(); 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      HtmlElement next = webBrowser1.Document.GetElementById("pnnext"); 

      if (_Pages <= 90) 
      { 
       if (null != next) 
       { 
        string href = next.GetAttribute("href"); 
        webBrowser1.Navigate(href); 
        _Pages++; 
       } 
       else 
       { 
        timer1.Stop(); 
        MessageBox.Show("Next button not found"); 
       } 
      } 
      else 
      { 
       timer1.Stop(); 
       MessageBox.Show("Done"); 
      } 
     } 

     private void goButton_Click(object sender, EventArgs e) 
     { 
      webBrowser1.Navigate(textBox1.Text); 
     } 

     private void freeMemButton_Click(object sender, EventArgs e) 
     { 
      MemoryManagement.FlushMemory(); 
     } 
    } 

    public class MemoryManagement 
    { 
     [DllImport("kernel32.dll")] 
     public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max); 

     public static void FlushMemory() 
     { 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
      if (Environment.OSVersion.Platform == PlatformID.Win32NT) 
      { 
       SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); 
      } 
     } 
    } 
} 

मुझे क्या पर दिया Google झटपट के साथ गूगल में कुछ भी खोज है, और उसके बाद startButton (जो invokes startButton_Click)। लगभग 80 पृष्ठों के बाद मैं stopButton दबाता हूं, फिर "लगभग: खाली" पर नेविगेट करता हूं, फिर Google पर वापस जाता हूं और कुछ और खोजता हूं और startButton फिर से दबाता हूं।

मैंने पहली बार अपने पीसी पर इसका परीक्षण किया, जिसमें 6 जीबी रैम है। जब मैं 1.5 जीबी तक पहुंच गया तो एप्लिकेशन ने जवाब देना बंद कर दिया लेकिन मुझे OutOfMemory अपवाद नहीं मिला। फिर मैंने विंडोज 7 और 1 जीबी रैम के साथ वर्चुअल मशीन पर इसका परीक्षण किया। जब यह लगभग 300 एमबी तक पहुंच गया तो मेरे आवेदन में वेब ब्राउजर अप्रतिबंधित हो गया।

यदि मैं freeMem बटन दबाता हूं, जो freeMemButton_Click पर कॉल करता है, तो स्मृति वापस चला जाता है (लेकिन मेरा संपादन 2 देखें)। तो यह मेरी समस्या हल करता है। लेकिन अब मेरा सवाल है कि मुझे SetProcessWorkingSetSize पर कॉल करने की आवश्यकता क्यों है? क्या यह विंडोज स्वचालित रूप से स्मृति को मुक्त नहीं करना चाहिए? साथ ही, मुझे यकीन नहीं है कि उस फ़ंक्शन को कॉल करने पर कोई दुष्प्रभाव होगा।

मुझे यकीन है कि यह एक बग है। क्या मुझे आगे बढ़ना चाहिए और इसकी रिपोर्ट करनी चाहिए?

संपादित 2: मैंने स्टीफन के समाधान का परीक्षण किया (SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1) पर कॉल किया) और इसे ठीक नहीं किया। स्मृति प्रबंधक पर स्मृति नीचे चला गया, लेकिन यह केवल स्पष्ट है। उस समारोह को कॉल न करने पर कई ब्राउज़र नेविगेशन किए जाने के बाद यह अनुत्तरदायी बनने के बाद आवेदन अप्रतिबंधित हो गया।

+0

क्या आप वेब ब्राउज़र पर किसी ईवेंट हैंडलर को जोड़ रहे हैं? –

+0

नहीं। बस आप जो कोड देखते हैं। – Juan

+0

इस पर कोई अद्यतन? – atwellpub

उत्तर

3

विंडोज़ वास्तव में मुक्त स्मृति वापस नहीं करता है अगर इसके न ही कारण हैं। और एकमात्र कारण यह होगा कि अगर किसी अन्य ऐप को उस मेमोरी की आवश्यकता होती है और अब कोई अन्य मेमोरी उपलब्ध नहीं है। यही कारण है कि ऐसा लगता है कि स्मृति उपयोग बढ़ता है।

बुला

SetProcessWorkingSetSize कोशिश (GetCurrentProcess(), -1, -1);

कभी-कभी - यह ओएस को सभी मुक्त स्मृति को वापस ओएस पर वापस करने के लिए मजबूर करेगा।

+0

क्या विंडोज़ के बिना 1.5 जीबी तक पहुंचना सामान्य है? – Juan

+0

कृपया मेरा संपादन देखें। – Juan

+0

मैं एक परीक्षण चलाता हूं। यह ठीक नहीं करता है। मेमोरी टास्क मैनेजर पर रिलीज होती है, लेकिन उस फ़ंक्शन को कॉल न करने पर ब्राउज़र नेविगेशन के समान होने के बाद एप्लिकेशन अप्रतिबंधित हो जाता है। – Juan

0

मुझे लगता है कि HtmlElement pnext जारी नहीं किया गया है, क्योंकि यह ComObject है, और ब्राउज़र नियंत्रण में एक बग हो सकता है।

pnext का प्रयास करें। कृपया या मार्शल को आजमाएं। कृपया रिलीज़ करने के लिए कॉमऑब्जेक्ट का उदाहरण प्राप्त करें।

+0

बस 'if (null! = Next) मार्शल.ReleaseComObject (next.DomElement) जोड़ने की कोशिश की; 'मेरी' timer1_Tick' विधि के अंत तक लाइन, लेकिन कोई फर्क नहीं पड़ता। 1 जीबी तक पहुंचे – Juan

+0

कृपया –

+0

नेविगेट करने से पहले MemoryManagement.FlushMemory को कॉल करने का प्रयास करें मैंने यह भी कोशिश की। यह काम नहीं करता है (मेरा अंतिम संपादन देखें)। – Juan

0

वेबब्रोसर के साथ काम करते समय, मुझे पता चला कि "दस्तावेज" घटना का इंतजार करना और यह जांचना महत्वपूर्ण है कि "राज्य" पूरा हो गया है या नहीं, अगले पृष्ठ पर नेविगेट करना है। वरना नेविगेशन रद्द करने और दस्तावेज़-पूरा राज्य (निरस्त) नेविगेट bevore के लिए फिर से प्रतीक्षा करें ....

हो सकता है कि टाइमर का उपयोग करते हैं और नहीं Webbrowser की राज्य की जाँच के लिए एक समस्या

के साथ अगले बात हो सकती वेबब्रोसर-कंट्रोल यह है कि आप इसका उपयोग मल्टीथ्रेड/बैकग्राउंडर में नहीं कर सकते क्योंकि इसे एसटीए होना आवश्यक है .... (अक्सर उत्तरदायी आवेदन के साथ समस्याएं उत्पन्न होती हैं)

"फुल-कॉन्टोल" (पार्सिंग वेबसाइट्स) का उपयोग करके समाधान। मेरे लिए नेट, WebRequest/Webresponse का उपयोग करना था, आप इसका परिणाम Webbroswer पर डाल सकते हैं। यदि आप चाहते हैं कि DOM को "ऑटो" निष्पादित किया जाए तो दस्तावेज़ फिर से करें, इसे मल्टीथ्रेडेड, आसानी से सेट टाइमआउट का उपयोग करें एस/प्रॉक्सी wich मुझे वेबब्रोसर-नियंत्रण का उपयोग करने से अधिक आरामदायक पाया।

फिर भी मैं सफलतापूर्वक कार्यान्वित एक Webbrowser नियंत्रण यहाँ से संकेत का उपयोग कर एक अन्य परियोजना में पृष्ठों को पार्स (How to Fix the Memory Leak in IE WebBrowser Control?)

एक और "अजीब" Winforms-प्रोग्रामिंग के साथ पतली मैं बाहर है पाया है, यह है कि लगता है कि एक GC.Collect जब खिड़की को फिर से खोला जाता है तो ट्रिगर होता है -> क्या यह mem-use को कम करता है? (शायद स्टीफन की पोस्ट भी इस मुद्दे के संदर्भ में)

+0

दुर्भाग्यवश मैंने उन सभी को आजमाया (आपके लिंक में समाधान, ऐप को कम करने) और कुछ भी काम नहीं किया। मैंने ट्रैवललॉग प्रविष्टियों को मिटाने का भी प्रयास नहीं किया। – Juan

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