दिलचस्प पोस्ट
ExecuteReader को एक खुला और उपलब्ध कनेक्शन की आवश्यकता है। कनेक्शन का वर्तमान स्थिति कनेक्ट हो रहा है Node.js और एक्सप्रेस 4 पर मार्गों को अलग कैसे करें? जावास्क्रिप्ट में किसी वस्तु के सभी तरीकों को मुद्रित करने का कोई तरीका है? डेटासेट की तुलना में डेटार तेज है, जब डेटासेट को पॉपुलेट किया जा सकता है? एंड्रॉइड अनुवाद एनीमेशन के बाद एनीमेशन रिसेट क्लिक किए जाने पर एक लिंक खोलने के कई पृष्ठों को कैसे बनाएं फायदे बनाम। स्थानीय रूप से jQuery के होस्ट होने का नुकसान सिंक्रनाइज़ ब्लॉक के बजाय सिंक्रनाइज़ किए गए विधि का उपयोग करने के लिए एक फायदा है? पायथन में "ज़ोर देना" का क्या उपयोग है? कॉलिंग सुपर () file_get_contents () मुझे 403 निषिद्ध करें एक और ऐप में अवरुद्ध / ब्लॉक प्रसारण रिसीवर अक्षांश और देशांतर निर्देशांक का उपयोग करके स्थान से समय क्षेत्र कैसे प्राप्त करें? वितरित Jar फ़ाइल के भीतर एंड्रॉइड संसाधन फ़ाइलें पैकेजिंग UITableView किया SelectionRowAtIndexPath: पहली नल पर नहीं बुलाया जा रहा है

कैसे .net Webbrowser नियंत्रण में स्मृति रिसाव के आसपास पाने के लिए?

यह एक व्यापक रूप से जाना जाता है, जो पुराने .NET Webbrowser नियंत्रण के साथ है।

सारांश: .NET वेबब्रॉसर नियंत्रण होने पर किसी पृष्ठ को नेविगेट करने से स्मृति उपयोग बढ़ जाता है जो कि कभी भी मुफ़्त नहीं होता है।

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

एक आवेदन के लिए मेरी वर्तमान आवश्यकताओं में इसे लंबे समय तक चलना शामिल है, एक सीमित IE7 ब्राउज़र विंडो प्रदर्शित करना। हुक, बीएचओ और समूह नीतियों के कुछ बास्टर्ड सेटअप के साथ आईई 7 को चलाने के लिए वांछित नहीं है, यद्यपि वह इस समय फ़ॉलबैक की तरह दिख रहा है एक विंडोज़ प्रपत्र अनुप्रयोग में एक ब्राउज़र को एम्बेड करना है मेरे लिए एक अलग ब्राउज़र आधार का उपयोग करना एक विकल्प नहीं है आईई 7 आवश्यक है

इस ज्ञात स्मृति रिसाव से संबंधित पिछले धागे और लेख:

  • http://www.vbforums.com/showthread.php?t=644658
  • IE वेबब्राउजर नियंत्रण में मेमोरी लीक कैसे ठीक करें?
  • एकाधिक विंडो में WPF WebBrowser नियंत्रण का उपयोग करते समय मेमोरी रिसाव
  • http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8/
  • http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a2efea4-5e75-4e3d-856f-b09a4e215ede
  • http://dotnetforum.net/topic/17400-appdomain-webbrowser-memory-leak/

अक्सर प्रस्तावित सुधार जो काम नहीं करते हैं:

  • अलग-अलग पृष्ठों पर जाकर कोई फर्क नहीं पड़ता। के बारे में: रिक्त रिसाव ट्रिगर इसमें पृष्ठ को जावास्क्रिप्ट या किसी अन्य अतिरिक्त तकनीक की आवश्यकता नहीं है
  • इंटरनेट एक्सप्लोरर के विभिन्न संस्करणों का उपयोग करना कोई फर्क नहीं पड़ता। 7, 8, और 9 सभी समान लक्षण प्रदर्शित करते हैं, और जहाँ तक मैंने सुना है, सभी संस्करणों में नियंत्रण में एक ही स्मृति रिसाव होता है।
  • नियंत्रण के निपटान (आईएनजी) मदद नहीं करता है।
  • कचरा एकत्र करना मदद नहीं करता है (वास्तव में, मैंने इस में किए गए शोध को इंगित किया है कि रिसाव अप्रबंधित COM कोड में है जो वेबब्रॉवर्स नियंत्रण को लपेटता है।)
  • 1, -1 (सेटप्रक्रियावर्किंगसेटसेट () या सिममिल्टर की प्रक्रिया को कम करने और सेट करने की प्रक्रिया।) केवल भौतिक स्मृति उपयोग को कम कर देता है, वर्चुअल मेमोरी पर कोई प्रभाव नहीं पड़ता है।
  • वेबब्राउजर को कॉल करना। बंद करें () एक समाधान नहीं है, और कुछ भी लेकिन स्थिर वेबपेजों का उपयोग करने के लिए कार्यक्षमता को तोड़ता है, बिना लीक को थोड़ा कम करने के अलावा,
  • एक दस्तावेज के लिए इंतजार करने से पहले पूरी तरह से लोड होने से पहले किसी दूसरे को नेविगेट करने में मजबूर भी मदद नहीं करता है।
  • एक अलग ऐप में नियंत्रण लोड हो रहा है डॉमैन समस्या को ठीक नहीं करता है। (मैंने यह स्वयं नहीं किया है, लेकिन अनुसंधान से पता चलता है कि इस मार्ग से कोई सफलता नहीं है।)
  • एक अलग आवरण का उपयोग करना जैसे कि csexwb2 मदद नहीं करता, क्योंकि यह एक ही समस्या से ग्रस्त है
  • अस्थाई इंटरनेट फ़ाइलें कैश साफ़ करना कुछ नहीं करता है समस्या सक्रिय मेमोरी में है, डिस्क पर नहीं।

मेमोरी को मंजूरी दी जाती है जब पूरे एप्लिकेशन को बंद कर दिया जाता है और पुनरारंभ होता है।

मैं अपने खुद के ब्राउज़र नियंत्रण को COM या Windows API में सीधे लिखने के लिए तैयार हूं, अगर यह समस्या के लिए निश्चित रूप से तय हो। बेशक, मैं एक कम जटिल तय पसंद करेंगे; मैं चीज़ों को करने के लिए निचले स्तर तक जाने से बचना चाहूंगा, क्योंकि मैं ब्राउज़र के समर्थित सुविधाओं के संदर्भ में पहिये को दोबारा बदलना नहीं चाहता हूं। Letlone आईई 7 सुविधाओं और गैर-मानक व्यवहार को रोल-अपनी-अपनी शैली ब्राउज़र में डुप्लिकेट कर रहा है

मदद?

Solutions Collecting From Web of "कैसे .net Webbrowser नियंत्रण में स्मृति रिसाव के आसपास पाने के लिए?"

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

यदि संभव हो तो मैं एक अलग दृष्टिकोण का सुझाव दूंगा वेब ब्राउज़र नियंत्रण का उपयोग करने वाला एक अलग एप्लिकेशन बनाएं और इसे अपने ऐप्लिकेशन से प्रारंभ करें अपने स्वयं के मौजूदा अनुप्रयोग में नव निर्मित एप्लिकेशन को एम्बेड करने के लिए यहां वर्णित विधि का उपयोग करें। WCF या .NET रिमोटिंग का उपयोग करते हुए उस ऐप्लिकेशन से संचार करें। बाल प्रक्रिया को समय-समय पर पुनः आरंभ करने के लिए इसे बहुत मेमोरी लेने से रोकें

यह बिल्कुल जटिल समाधान है और पुनरारंभ प्रक्रिया संभवतः बदसूरत दिख सकती है। हो सकता है कि आप हर बार उपयोगकर्ता को किसी अन्य पृष्ठ पर नेविगेट करने के दौरान पूरे ब्राउज़र एप्लिकेशन को पुनरारंभ करने का सहारा ले सकें।

मैंने औदोन का कोड लिया (यह मेरे लिए काम किया, धन्यवाद!) और दो छोटी चीजों को बदल दिया:

  1. IKeyboardInputSite एक सार्वजनिक इंटरफ़ेस है और विधि अपंजीकृत () है , इसलिए हमें * _keyboardInputSinkChildren * संग्रह के संदर्भ प्राप्त करने के बाद प्रतिबिंब का उपयोग करने की आवश्यकता नहीं है

  2. के रूप में हमेशा अपने खिड़की वर्ग (विशेष रूप से MVVM में) के लिए एक सीधा संदर्भ नहीं है, मैं एक विधि GetWindowElement (निर्भरता ऑब्जेक्ट तत्व) जो दृश्य ट्री के माध्यम से traversing द्वारा आवश्यक संदर्भ देता है जोड़ा

धन्यवाद, धन्यवाद

 public void Dispose() { _browser.Dispose(); var window = GetWindowElement(_browser); if (window == null) return; var field = typeof(Window).GetField("_swh", BindingFlags.NonPublic | BindingFlags.Instance); var valueSwh = field.GetValue(window); var valueSourceWindow = valueSwh.GetType().GetField("_sourceWindow", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(valueSwh); var valuekeyboardInput = valueSourceWindow.GetType().GetField("_keyboardInputSinkChildren", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(valueSourceWindow); var inputSites = valuekeyboardInput as IEnumerable<IKeyboardInputSite>; if (inputSites == null) return; var currentSite = inputSites.FirstOrDefault(s => ReferenceEquals(s.Sink, _browser)); if (currentSite != null) currentSite.Unregister(); } private static Window GetWindowElement(DependencyObject element) { while (element != null && !(element is Window)) { element = VisualTreeHelper.GetParent(element); } return element as Window; } 

आप सभी को धन्यवाद!

मुख्य फ़ार्म पर निजी क्षेत्रों से संदर्भों को प्रतिबिंबित करने और संदर्भों को हटाने का स्पष्ट स्मृति लीक करने का एक तरीका है। यह एक अच्छा समाधान नहीं है, लेकिन हताश लोगों के लिए यह कोड है:

 //dispose to clear most of the references this.webbrowser.Dispose(); BindingOperations.ClearAllBindings(this.webbrowser); //using reflection to remove one reference that was not removed with the dispose var field = typeof(System.Windows.Window).GetField("_swh", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var valueSwh = field.GetValue(mainwindow); var valueSourceWindow = valueSwh.GetType().GetField("_sourceWindow", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSwh); var valuekeyboardInput = valueSourceWindow.GetType().GetField("_keyboardInputSinkChildren", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSourceWindow); System.Collections.IList ilist = valuekeyboardInput as System.Collections.IList; lock(ilist) { for (int i = ilist.Count-1; i >= 0; i--) { var entry = ilist[i]; var sinkObject = entry.GetType().GetField("_sink", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (object.ReferenceEquals(sinkObject.GetValue(entry), this.webbrowser.webBrowser)) { ilist.Remove(entry); } } } 

WPF WebBrowser घटक के साथ विभिन्न दिशाओं ( Win32 वर्कसेटिंग / कॉम SHDocVw इंटरफेस, आदि ) से मेमोरी मुद्दे से इस सटीक लड़ाई के बाद, मुझे पता चला कि हमारे लिए समस्या ActiveXHost प्लगइन IE ActiveXHost में अप्रबंधित संसाधनों पर पकड़ रहा था और उन्हें रिलीज़ नहीं करने के बाद WebBrowser.Dispose() कह रहा है। यह समस्या प्रायः जावास्क्रिप्ट द्वारा बनाई गई है जो ठीक से बर्ताव नहीं कर रही है। अजीब बात यह है कि जावास्क्रिप्ट नियमित रूप से IE में ठीक काम करता है – बस WebBrowser नियंत्रण में से नहीं। मुझे लगता है कि कचरा संग्रह दो एकीकरण बिंदुओं के बीच अलग है क्योंकि IE वास्तव में कभी बंद नहीं हो सकता है।

एक बात मैं सुझाव देता हूं कि यदि आप स्रोत पृष्ठों को संलेखित कर रहे हैं तो सभी जेएस घटकों को निकालना है और धीरे-धीरे उन्हें वापस जोड़ना है। एक बार जब आप हमलावर जेएस प्लगइन की पहचान करें ( जैसे हमने किया ) – समस्या का समाधान करना आसान होना चाहिए। हमारे मामले में हमने सिर्फ $("#jqgrid").jqGrid('GridDestroy') को ठीक से इवेंट्स को निकालने के लिए और संबंधित DOM तत्वों को बनाया था। WebBrowser.InvokeScript माध्यम से ब्राउजर को बंद कर दिया गया है, इसने इसे लागू करके हमारे लिए इस समस्या का ख्याल रखा है। WebBrowser.InvokeScript

यदि आपके पास नेविगेट किए गए स्रोत पृष्ठों को संशोधित करने की क्षमता नहीं है – आपको DOM ईवेंट को साफ़ करने के लिए कुछ जेएस को पृष्ठ में डालना होगा और स्मृति को लीक करने वाले तत्वों को साफ करना होगा। यह अच्छा होगा यदि माइक्रोसॉफ्ट इस पर एक प्रस्ताव पाया, लेकिन अभी के लिए हम जेएस प्लगइन्स की जांच कर रहे हैं जो शुद्ध होने की आवश्यकता है

नीचे समाधान मेरे लिए काम किया है:

 Protected Sub disposeBrowers() If debug Then debugTrace() If Me.InvokeRequired Then Me.Invoke(New simple(AddressOf disposeBrowers)) Else Dim webCliffNavigate As String = webCliff.Url.AbsoluteUri Me.DollarLogoutSub() If dollarLoggedIn Then Exit Sub End If 'Dim webdollarNavigate As String = webDollar.Url.AbsoluteUri Me.splContainerMain.SuspendLayout() Me.splCliffDwellers.Panel2.Controls.Remove(webCliff) Me.splDollars.Panel2.Controls.Remove(webDollar) RemoveHandler webCliff.DocumentCompleted, AddressOf webCliff_DocumentCompleted RemoveHandler webDollar.DocumentCompleted, AddressOf webDollar_DocumentCompleted RemoveHandler webCliff.GotFocus, AddressOf setDisposeEvent RemoveHandler webCliff.LostFocus, AddressOf setDisposeEvent RemoveHandler webDollar.GotFocus, AddressOf setDisposeEvent RemoveHandler webDollar.LostFocus, AddressOf setDisposeEvent webCliff.Stop() webDollar.Stop() Dim tmpWeb As SHDocVw.WebBrowser = webCliff.ActiveXInstance System.Runtime.InteropServices.Marshal.ReleaseComObject(tmpWeb) webCliff.Dispose() tmpWeb = webDollar.ActiveXInstance System.Runtime.InteropServices.Marshal.ReleaseComObject(tmpWeb) webDollar.Dispose() tmpWeb = Nothing webCliff = Nothing webDollar = Nothing GC.AddMemoryPressure(50000) GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForFullGCComplete() GC.Collect() GC.RemoveMemoryPressure(50000) webCliff = New WebBrowser() webDollar = New WebBrowser() webCliff.CausesValidation = False webCliff.Dock = DockStyle.Fill webDollar.CausesValidation = webCliff.CausesValidation webDollar.Dock = webCliff.Dock webDollar.ScriptErrorsSuppressed = True webDollar.Visible = True webCliff.Visible = True Me.splCliffDwellers.Panel2.Controls.Add(webCliff) Me.splDollars.Panel2.Controls.Add(webDollar) Me.splContainerMain.ResumeLayout() 'AddHandler webCliff.DocumentCompleted, AddressOf webCliff_DocumentCompleted 'AddHandler webDollar.DocumentCompleted, AddressOf webDollar_DocumentCompleted 'AddHandler webCliff.GotFocus, AddressOf setDisposeEvent 'AddHandler webCliff.LostFocus, AddressOf setDisposeEvent 'AddHandler webDollar.GotFocus, AddressOf setDisposeEvent 'AddHandler webDollar.LostFocus, AddressOf setDisposeEvent webCliff.Navigate(webCliffNavigate) disposeOfBrowsers = Now.AddMinutes(20) End If End Sub 

शुभकामनाएं, लैला

मुझे लगता है कि यह सवाल लंबे समय तक अनुत्तरित नहीं हुआ है। एक ही सवाल के साथ कई धागे लेकिन निर्णायक जवाब नहीं।

मुझे इस मुद्दे के लिए एक काम मिल गया है और आप सभी के साथ साझा करना चाहते हैं जो अब भी इस मुद्दे का सामना कर रहे हैं।

चरण 1: फॉर्म 2 का एक नया फ़ॉर्म बनाएं और उस पर एक वेब-ब्राउज़र नियंत्रण जोड़ें step2: फॉर्म 1 में जहां आप अपना वेबब्रॉसर नियंत्रण रखते हैं, बस इसे हटा दें। चरण 3: अब, फॉर्म 2 पर जाएं और इस वेबब्रोवर नियंत्रण के लिए एक्सेस मॉडरेटर को सार्वजनिक बनाओ ताकि यह फॉर्म 1 में 4 तक पहुंचा जा सके: फॉर्म 1 में एक पैनल बनाएं और फॉर्म 2 का ऑब्जेक्ट बनाएं और इसे पैनल में जोड़ें। फॉर्म 2 एफएम = नया फॉर्म 2 (); frm.TopLevel = false; frm.Show (); panel1.Controls.Add (frm); step5: नीचे दिए गए कोड को नियमित अंतराल frm पर कॉल करें। नियंत्रण। निकालें (frm.webBrowser1); frm.Dispose ();

बस। अब जब आप इसे चलाते हैं, तो आप देख सकते हैं कि वेब ब्राउजर नियंत्रण लोड हो रहा है और यह नियमित अंतराल पर निपटा जाएगा और आवेदन की अधिक लटका नहीं है।

आप इसे और अधिक कुशल बनाने के लिए नीचे कोड जोड़ सकते हैं

  IntPtr pHandle = GetCurrentProcess(); SetProcessWorkingSetSize(pHandle, -1, -1); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); 

वेब ब्राउज़र नियंत्रण के बजाय किसी भी नेट फ्रेमवर्क के मुद्दे पर विश्वास करें। एक हैंडलर के साथ ब्राउज़र की नेविगेटेड घटना की ओर झुकना जो ब्राउज़र का निपटान करेगा और फिर इसके बारे में नेविगेट करेगा: रिक्त एक अच्छा समाधान होगा। उदाहरण के लिए:

 private void RemoveButton_Click(object sender, RoutedEventArgs e) { var browser = (WebBrowser) _stackPanel.Children[_stackPanel.Children.Count - 1]; _stackPanel.Children.RemoveAt(_stackPanel.Children.Count-1); NavigatedEventHandler dispose = null; dispose = (o, args) => { browser.Navigated -= dispose; browser.Dispose(); }; browser.Navigated += dispose; browser.Navigate(new Uri("about:blank")); } 

इस समाधान की कोशिश करो, मुझे पता है कि यह आदर्श नहीं है। प्रत्येक पृष्ठ लोड के बाद कोड पेस्ट करें

 System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess(); try { loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet - 1); loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet - 1); } catch (System.Exception) { loProcess.MaxWorkingSet = (IntPtr)((int)1413120); loProcess.MinWorkingSet = (IntPtr)((int)204800); }