8
votes

Problème de mémoire WebBrowser

J'ai une application .NET qui doit utiliser un WebBrowser code> pour naviguer automatiquement via un tas de pages. Mais si je passe, par exemple, Google et définit Google Instant sur, puis recherchez quelque chose et navigue manuellement via le bouton Suivant à plusieurs reprises, la mémoire utilisée par mon application commencera à augmenter.

Le problème peut être que Google Instant Il est en quelque sorte gardant les données des pages précédentes, mais même après que je navigue ailleurs, comme "à propos de: vide", la mémoire utilisée ne diminuera pas. Ce problème se produit également avec IE 9. J'ai commencé à écrire ma mémoire utilisée à la page 60 et c'est ce que j'ai obtenu (avec IE 9): p> xxx pré>

afin que vous puissiez voir La mémoire augmente presque de 30 à 35 Mo toutes les 10 pages. Ce ne serait pas un problème si la mémoire serait libérée après que je navigue loin de Google. Mais n'est pas. P>

J'ai aussi essayé Ce et n'a rien fait. P>

edit: strong> J'ai fait un projet juste pour tester cela. Voici mon form1 code> CODE: P>

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);
            }
        }
    }
}


1 commentaires

Vous attachez-vous un gestionnaire d'événements sur le navigateur Web?


3 Réponses :


4
votes

Windows ne retourne pas vraiment la mémoire libérée s'il n'y en a ni raison. Et la seule raison serait si une autre application nécessite cette mémoire et il n'y a plus d'autre mémoire disponible. C'est pourquoi il semble que l'utilisation de la mémoire augmente.

essayez d'appeler

setProcessworkingSetsize (getCurrentProcess (), -1, -1);

Parfois, cela obligera le système d'exploitation à retourner tout mémoire libéré au système d'exploitation.


2 commentaires

Est-il normal d'atteindre 1,5 Go sans Windows libérant la mémoire?


Je cours un test. Cela ne le répare pas. La mémoire semble relâche sur le gestionnaire de tâches, mais l'application devient insensible après la même quantité de navigations de navigateur qu'il faut pour ne pas répondre lorsqu'il n'appelle pas cette fonction.



0
votes

Je pense que htmlelement pnext n'est pas publié, car il est comobject, et il peut y avoir un bogue dans le contrôle du navigateur.

Essayez Pnext.Release ou essayez marshal.Release et obtenez l'instance de ComObject à la libération.


2 commentaires

Je viens d'essayer d'ajouter le si (null! = Suivant) marshal.releasecomObject (Next.domelement); Ligne à la fin de mon Timer1_Tick Méthode mais n'a pas fait de différence. Atteint 1 gb.


S'il vous plaît essayez d'appeler memorocanagement.flushmemory avant de naviguer



0
votes

Lorsque vous travaillez avec WebBrowser, j'ai constaté qu'il est important d'attendre l'événement "DocumentComplet" et vérifiez si "l'état" est "terminé" Bevore Navigation sans page suivante. Sinon annuler la navigation et attendre à nouveau pour l'état du document (avorté) Bevore naviguer ....

pourrait être que l'utilisation des minuteries et ne pas vérifier l'état de Webbrowser pourrait être un problème

La prochaine chose avec le WebBrowser-Control est, que vous ne pouvez pas l'utiliser dans Multhread / Backworker, car elle nécessite d'être STA .... (pose souvent des problèmes d'application insensible)

La solution pour "Ful-CONTOL" (sites Web analysants) à l'aide de .NET pour moi, était d'utiliser WebRequest / Webresponse, vous pouvez lancer à nouveau le résultat de celui de Webbroswer.document si vous voulez que le DOM soit "Auto" exécuté, utilisez-le multithreadé, facilement défini des délais d'attente / proxy que j'ai trouvé plus confortable que l'utilisation de WebBrowser-Control.

Néanmoins j'ai mis en œuvre avec succès une pages d'analyse de contrôle WebBrowser dans un autre projet à l'aide de conseils d'ici ( Comment réparer la fuite de mémoire dans la commande WebBrowser IE? )

Un autre "drôle" mince avec WinForms-Programmation J'ai découvert, qu'il semble qu'un gc.Collect est déclenché lorsque la fenêtre est minimisée à nouveau -> Est-ce que cela diminue la mousse? (Le message de Maybee Stefan références également à ce problème)


1 commentaires

Malheureusement, j'ai essayé tout cela (les solutions dans votre lien, minimisant l'application) et rien n'a fonctionné. J'ai même essayé d'effacer les entrées de travellog en vain.