Comment faire pour Réparer la Fuite de Mémoire dans IE Contrôle WebBrowser?
Je suis en train d'intégrer un Contrôle WebBrowser dans un C# Winform Application. Cela semble assez facile. Cependant, j'ai découvert que le contrôle WebBrowser mange beaucoup de mémoire chaque fois que j'appelle la méthode de navigation. La mémoire n'est jamais sorti. L'utilisation de la mémoire se développe et grandit...
Beaucoup de gens sur le net d'avoir exactement le même problème mais je n'ai pas trouvé une réponse satisfaisante encore. C'est le meilleur des discussions sur ce thème que j'ai trouvé jusqu'à présent:
Fuite de mémoire dans IE Contrôle WebBrowser
Une personne a suggéré une mise à niveau vers IE8 pour résoudre le problème.
Cependant j'ai besoin d'une solution qui fonctionne si l'utilisateur dispose de la dernière version de IE est installé ou pas. Je n'ai pas de contrôle sur l'environnement des utilisateurs.
Quelqu'un sait comment libérer la mémoire utilisée par le contrôle WebBrowser? Existe-il des solutions de contournement? Existe-il des alternatives pour le contrôle WebBrowser?
Mise à jour:
Je viens de faire quelques tests. Au travail je suis sous Windows XP et IE6. La mémoire n'est pas qui y poussent. La mémoire augmente lors de l'appel de la méthode de naviguer, mais qu'il est libéré après un certain temps. À la maison, je suis sous Vista et mis à niveau vers IE8. Ici aussi je ne vois pas le problème plus. On dirait que le problème est spécifique à la version IE7. Donc, la question devrait être reformulée pour "Comment Réparer la Fuite de Mémoire dans IE Contrôle WebBrowser lorsque IE7 est installé". Quelqu'un peut-il confirmer que ce problème est spécifique à la version IE7?
- Il y a une fuite de mémoire si vous ajouter des gestionnaires d'événements pour toute la navigué éléments. À corriger, vous devrez garder un dictionnaire de tous les éléments (inclure le document de niveau supérieur de trop), puis dans le OnDocumentCompleted fonction de (), supprimer les gestionnaires d'événements un par un tout en appelant marshall.ReleaseComObject(o.DomDocument) dans une boucle, puis, enfin, relâchez le document de niveau supérieur via le Maréchal.ReleaseComObject(document.DomDocument).
Vous devez vous connecter pour publier un commentaire.
mon application a également été constamment consommant de la mémoire lors de la navigation, et ne libère pas plus.
j'ai la solution de mouillage pour moi ici:
http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8
pour l'exhaustivité de mauvais post notables extrait:
-- code pour appeler quand vous voulez pour réduire la mémoire
tous les honneurs:
http://social.msdn.microsoft.com/profile/mike_t2e/?type=forum&referrer=http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8
pour l'affichage de la solution.
et
http://ict-engineer.blogspot.com/2010/10/net-webbrowser-control-memory-leak.html
pour le RÉFÉRENCEMENT avec la droite, de sorte que je pouvais le trouver 😉
salutations
edit: si cela vous aide à résoudre rapidement un ti - bon. mais vous devriez overthing la conception de votre application, le modèle que vous utilisez le cas échéant , refactore la chose, si vous construisez sur beaucoup plus longtemps ....
Je viens de créer une application simple avec un contrôle de navigateur web pour essayer de le dupliquer vos résultats. Ce que j'ai trouvé était que, oui, à chaque fois que vous accédez à une page, la mémoire utilisée augmente de façon significative. CEPENDANT, ce n'est PAS une fuite de mémoire, parce que si vous continuez à naviguer, vous verrez que peu de temps après, la mémoire diminue de façon significative, indiquant que le garbage collector ne c'est chose. Pour le prouver, j'ai forcé le Garbage Collector pour collecter chaque fois que j'ai appelé à Naviguer et à la mémoire totale utilisée restèrent à peu près au même montant après chaque appel de naviguer.
Ainsi, alors qu'il N'en rack de la mémoire chaque fois que vous "Naviguez" ce n'est PAS une fuite de mémoire, et vous avez la mémoire sera libérée. Si c'est de ratisser trop vite, il suffit d'appeler GC.Collect();
L'IDÉE de BASE est,
"Tuer moi-même, et de renaître."
Windows permettra de résoudre tous les problèmes de mémoire.
mais si vous Fermez votre application tout d'abord, vous ne pouvez pas démarrer une nouvelle.
Donc, en COMMENCER UNE NOUVELLE, et de FERMER L'ancienne.
Premier tour sur une nouvelle, et de désactiver une ancienne.
https://www.youtube.com/watch?v=aTBlKRzNf74
Si il y a un paramètre
Aller à l'école.cs
et, Aller à Form1.cs et de faire un autre Form1()
ou vous pouvez utiliser les fichiers temp !!!
Il y a un alternative de contrôle qui utilise Gecko (Le moteur de Firefox utilise) au lieu de Trident et fonctionne très bien avec le MSHTML interfaces.
Vos pages seront rendu Gecko, et vous aurez un contrôle complet sur les paramètres, de plugins, de sécurité et toutes les autres fonctionnalités personnalisables d'un navigateur.
L'inconvénient est que vous aurez besoin pour expédier Gecko avec votre application, j'ai utilisé l'équivalent de la version 2 de Firefox et c'est autour de 8 MO.
J'ai publié une application tout à fait il ya un moment que par rapport à IE et Firefox rendu les uns à côté des autres, à la fois la mise à jour que vous avez modifié le CSS. Je n'ai pas rencontré les problèmes de mémoire que vous avez eu avec le contrôle de navigateur web, mais j'ai trouvé le Gecko de contrôle très facile de travailler avec. Il n'a pas la même classe wrapper géré la .net contrôle WebBrowser a, mais il est assez facile de travailler autour de cela.
Selon MSDN, Le Système.De Windows.Les formulaires.Contrôle WebBrowser est un wrapper géré pour le contrôle ActiveX WebBrowser, et utilise quelle que soit la version de l'appareil est installé sur l'ordinateur de l'utilisateur.
Vous pouvez trouver dispose(bool) méthode dans les métadonnées de classe WebBrowser(Appuyez sur la touche F12 dans Visual Stuio) pour libérer des ressources non managées.(Jetez PAS())
Le code ici
Mais si vous essayez d'appeler le WebBrowser.Dispose(bool), erreur de compilateur CS1540 est indiqué.
WebBrowser classe prend en charge méthode dispose(bool), MAIS nous ne pouvons pas l'utiliser.
Je pense que WebBrowser classe a été conçu par le mauvais chemin.
J'ai une idée d'appeler le WebBrowser.Dispose(true).
C'EST TRÈS SIMPLE! mais ce n'est pas un bon moyen.
Exemple de Code ici(3 Boutons et 1 TextBox besoin)
Ce code peut empêcher la Fuite de Mémoire.
En résumé,
Vous avez juste besoin d'une classe.
Il est connu Fuite de Mémoire dans le contrôle WebBrowser. Voir la suite Microsoft KB article - KB893629.
J'ai rencontré ce problème lors de l'écriture d'un petit "diaporama" de l'application pour les différentes pages intranet utilisé par mon entreprise. La solution la plus simple que j'ai trouvé était de redémarrer l'application après une certaine période de temps fixe, une heure dans mon cas. Cette solution a bien fonctionné pour nous, car il n'y avait pas beaucoup d'interaction de l'utilisateur avec le navigateur.
Cela suppose bien sûr que vous avez un mécanisme de persistance en place.
Il semble que la navigation() méthode permet de conserver toutes les pages visitées dans le mémoire que vous pouvez utiliser le GoBack() la méthode, il n'y a pas de "fuite de mémoire" en fait. Mon programme de visites de la même Url à plusieurs reprises. La "fuite de mémoire" problème peut être éliminé à l'aide de la méthode Refresh() instand de Naviguer() la méthode, suivi par un GC.Collect(). Le Code est le suivant:
J'ai connu ce problème avec un simple contrôle webbrowser dans un formulaire. Il consulte une page web et y est resté. Selon le gestionnaire des tâches en moins de 10 minutes il a mangé jusqu'à 2 go de mémoire à partir de 120 mo.
Une solution simple pour mon projet était d'aller au contrôle webbrowser propriétés dans visual studio et changer le AllowNavigation " pour de faux. Maintenant quand je lance mon programme il reste à 120 mo. J'espère que cela aide quelqu'un!
Je suis en utilisant le Contrôle du Web dans une application, mais depuis mon application accède à une page que je n'ai pas remarqué le problème que vous avez mentionné.
Il y a un autre contrôle du web qui est en fait un wrapper et je ne sais pas si il a le même problème ou pas.
Vous pouvez le trouver ici.
J'ai été en cours d'exécution dans le même problème, comme une alternative, au lieu de naviguer vers une nouvelle page, j'ai simplement réécrit la même page html en utilisant le système.oi.streamreader/écrivain de l'objet et de l'appel d'une actualisation. Évidemment, cela ne fonctionnera pas dans une situation où le contenu pour le navigateur de la fed en ligne, mais elle fait l'affaire pour moi.
Aussi, je suis actuellement à l'aide de 8+ commandes du navigateur de tous les actifs en même temps pour servir de rapports à l'aide de javascript à l'intérieur de mon .net application. Comme un utilisateur d'un navigateur active, le html à laquelle les autres navigateurs sont de pointage, sont compensés et les navigateurs actualisé. Avec 8 navigateurs fonctionnant avec ces deux méthodes, je peux facilement garder mon application et en vertu de l'utilisation de la mémoire de Firefox avec seulement 3 onglets ouverts.
J'ai regardé sur internet et j'ai été incapable de trouver une réponse à ce problème. Je le fixe à l'aide de la ci-dessous:
Je sais que ce n'est pas la plus jolie ou la solution idéale, mais ça a très bien fonctionné pour moi.
-- Layla
Collez le code suivant après le chargement de la page
Je pense que cette question est restée sans réponse pendant un long moment maintenant. Autant de fils avec la même question mais pas de réponse concluante.
J'ai trouvé un travail autour de cette question et je voulais le partager avec vous tous qui êtes toujours confronté à ce problème.
etape 1: Créez un nouveau formulaire de dire form2 et ajouter un navigateur web de contrôle sur elle. etape 2: Dans la form1 où vous avez votre contrôle webbrowser, suffit de le retirer. etape 3: Maintenant, allez à la Form2 et de faire le modificateur d'accès pour ce contrôle webbrowser à être public, de sorte qu'il peut être consulté dans Form1 etape 4: Créer un panneau dans form1 et à créer l'objet de form2 et les ajouter dans le panneau. Form2 frm = new Form2 (); frm.TopLevel = false; frm.Show(); panel1.Les contrôles.Ajouter(frm); etape 5: Composez le code ci-dessous, à intervalles réguliers, la frm.Les contrôles.Supprimer(frm.webBrowser1); frm.Dispose();
C'est tout. Maintenant, lorsque vous l'exécutez, vous pouvez voir que le contrôle webbrowser chargé et elle sera disposé à intervalles réguliers et il n'y a pas plus accroché de la demande.
Vous pouvez ajouter le code ci-dessous pour le rendre plus efficace.
J'ai eu même des problèmes similaires. J'ai été l'envoi de plus de 5000 navigation demandes via un navigateur web pour gratter des pages dynamiques. Après environ 50 demande, je voudrais exécuter de mémoire que la navigation demande l'utilisation de la mémoire n'a pas été libéré après chaque demande. J'ai utilisé le webBrowser.Dispose() après la navigation, et il a résolu le problème. Il n'a pas à faire avec IE7 ou donc. Je suis de l'utilisation d'IE 11 et a obtenu le même problème. C'était parce que je n'étais pas de l'élimination de la navigation des Objets.
Espérons que cette aide.
Cela a fonctionné pour moi, pas si sûr à 100% efface la mémoire, il semble toujours garder en mémoire cache des pages, mais n'est plus grimpe à 500 mo de l'utilisation de la ram plus, il reste à 60 MO.
mon programme va à plusieurs reprises sur le même site, 3 pages différentes, une seule fois par l'utilisation, pas de ramper un grand nombre de pages ou de quoi que ce soit.
C'est presque la fin de 2017 et encore ce bug gênant est présent dans le WebBrowser.
J'ai essayé toutes les solutions ici et aucun d'entre eux travaillaient pour moi. Fuite de mémoire persiste... La shtrangest chose, c'est que quand je l'appelle:
Il en fait de réduire la mémoire de beaucoup de choses! mais quand la prochaine Naviguer instruction est appelée toutes les fuites de mémoire revient dans le champ d'application.... comme (si la mémoire est à 450 mo.. c'instructions réduit à environ 20 mo et à droite après l'appel .Naviguer(string) de nouveau, il saute à 460mb et une fuite de mémoire se poursuit...
J'ai même essayé d'en Disposer(), dans about:blank avant la prochaine page, le paramétrage de l'objet webbrowser à null et en créer un nouveau. Toutes ces tentatives d'automne en fuite de mémoire... c'est vraiment frustrant... d'autres solutions?
Il suffit de déclarer le contrôle WebBrowser à l'aide de la "aide" mot-clé. Il va arrêter une fuite de mémoire lors de l'appel de la navigation() la méthode plus. Je l'ai juste testé et il a bien fonctionné pour moi.