2013-09-24 52 views
0

所以我的问题是,我创建了一个应用程序供我个人使用,从一些网站获取html页面,然后在一些更改后在Web浏览器中显示它。每件事情都很好,但令我感到不安的是它正在采取的记忆。查询3-4个条款后,内存使用量达到大约300-400 MB。为什么这个应用程序需要大量的内存?

从应用程序的一些相关代码

void sentenceBox_Navigated(object sender, WebBrowserNavigatedEventArgs e) 
     { 
      GC.Collect(); 
     } 
    HtmlDocument hd; 
    Word w=new Word(); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     button1.Enabled = false; 
     status.Text = "Processing english req.."; 
     if (checkInHis(queryTxt.Text)) 
     { 
      sentenceBox.AllowNavigation = true; 
      richTextBox1.Text = w.engDefinition; 
      sentenceBox.DocumentText = w.engDefinition; 
      status.Text = "Word found in History.DONE!"; 
      button1.Enabled = true; 
      return; 
     } 
     if (w == null || w.engWordProp != queryTxt.Text) 
     { 
      w.engWordProp=queryTxt.Text; 
      w.loadEngDefn(); 
      w.engDefnLoadedEvent += new Word.engDefnLoaded(w_engDefnLoadedEvent); 
      return; 
     } 
     w.loadEngDefn(); 
     w.engDefnLoadedEvent += new Word.engDefnLoaded(w_engDefnLoadedEvent); 
    } 

    void w_engDefnLoadedEvent(Word sender, EventArgs data) 
    { 
     sentenceBox.AllowNavigation = true; 
     sentenceBox.DocumentText = sender.engDefinition; 
     sender.engDefnLoadedEvent -= w_engDefnLoadedEvent; 
     button1.Enabled = true; 
    } 

    private void addToHistory(Word w) 
    { 
     status.Text = "Saving offline..."; 
     if (!checkInHis(w.engWordProp)) 
     { 
     history.Add(w); 
//  label1.Text = w.engWordProp + " saved in localdb. Database size: " + history.Count; 

     w = null; 
     } 
     else 
     { 
//    label1.Text = w.engWordProp + " Skipped. Database size: " + history.Count; 

     } 
    } 

    private Boolean checkInHis(string p) 
    { 
     status.Text = "checking offline storage..."; 
     foreach (Word item in history) 
     { 
      if (item.engWordProp == p) 
      { 
       status.Text = "Word found in history."; 
       w = item; 
       return true; 
      } 
     } 
     status.Text = "Not found in offline database..."; 
     return false; 
    } 

    private void sentenceBox_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     ((WebBrowser)sender).AllowNavigation = false; 
    } 

    private void button2_Click_1(object sender, EventArgs e) 
    { 
     button2.Enabled = false; 
     status.Text = "Requesting hindi definition..."; 
     if (checkInHis(queryTxt.Text)) 
     { 
      sentenceBox.AllowNavigation = true; 
      sentenceBox.DocumentText = w.hindiDef; 
      status.Text = "DONE!"; 
      button2.Enabled = true; 
      return; 
     } 
     if (w == null || w.engWordProp != queryTxt.Text) 
     { 
      w.engWordProp=queryTxt.Text; 
      w.loadHinDefn(); 
      w.HindiDefLoadedEvent += new Word.hindiDefLoaded(w_HindiDefLoadedEvent); 
      return; 
     } 
     w.loadHinDefn(); 
     w.HindiDefLoadedEvent += new Word.hindiDefLoaded(w_HindiDefLoadedEvent); 
    } 

    void w_HindiDefLoadedEvent(Word sender, EventArgs data) 
    { 
     sentenceBox.AllowNavigation = true; 
     sentenceBox.DocumentText = sender.hindiDef; 
     button2.Enabled = true; 
     sender.HindiDefLoadedEvent -= w_HindiDefLoadedEvent; 
    } 

private void button3_Click(object sender, EventArgs e) 
    { 
     button3.Enabled = false; 
     saveWord(w); 
     button3.Enabled = true; 
    } 

    private void saveWord(Word w) 
    { 
     if (w.hindiDef == "") 
     { 
      w.loadHinDefn(); 
      w.HindiDefLoadedEvent += new Word.hindiDefLoaded(w_HindiDefLoadedEventforHindiSave); 
     } 
     if (w.engDefinition == "") 
     { 
      w.loadEngDefn(); 
      w.engDefnLoadedEvent += new Word.engDefnLoaded(w_engDefnLoadedEventforEnglishSave); 
     } 
     addToHistory(w); 
    } 

    void w_HindiDefLoadedEventforHindiSave(Word sender, EventArgs data) 
    { 
     sender.HindiDefLoadedEvent -= w_HindiDefLoadedEvent1; 
     sender.HindiDefLoadedEvent -= w_HindiDefLoadedEventforHindiSave; 
    } 
    void w_engDefnLoadedEventforEnglishSave(Word sender, EventArgs data) 
    { 
     sender.engDefnLoadedEvent -= w_engDefnLoadedEventforEnglishSave; 
     sender.engDefnLoadedEvent -= w_engDefnLoadedEventforEnglishSave; 
    } 

    void w_HindiDefLoadedEvent1(Word sender, EventArgs data) 
    { 
     saveWord(sender); 
     sender.HindiDefLoadedEvent -= w_HindiDefLoadedEvent1; 
    } 

    void w_engDefnLoadedEvent1(Word sender, EventArgs data) 
    { 
     sender.loadHinDefn(); 
     sender.HindiDefLoadedEvent += new Word.hindiDefLoaded(w_HindiDefLoadedEvent1); 
     sender.engDefnLoadedEvent -= w_engDefnLoadedEvent1; 
    } 

    void initWord(String query) 
    { 
     queryTxt.Text = query; 
     w.engWordProp=queryTxt.Text; 
     w.loadEngDefn(); 
     w.loadHinDefn(); 
     w.engDefnLoadedEvent += new Word.engDefnLoaded(w_engDefnLoadedEvent); 
     w.HindiDefLoadedEvent += new Word.hindiDefLoaded(w_HindiDefLoadedEvent); 
    } 

字类

public Word(string q) 
    { 
     wb1 = new WebBrowser(); 
     wb2=new WebBrowser(); 
     engWord = q; 
     hindiDef = ""; 
     engDefinition = ""; 
     flagE = false; 
     flagH = false; 
     engUrl = "http://oxforddictionaries.com/definition/english/" + q + "?q=" + q; 
     hindiUrl = "http://dict.hinkhoj.com/hindi-dictionary.php?word=" + q; 
     wb1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); ;     
     wb2.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); 
    } 

    public delegate void engDefnLoaded(Word sender, EventArgs data); 
    public event engDefnLoaded engDefnLoadedEvent; 
    protected void onEngDefnLoadCompleated(Word sender, EventArgs data) 
    { 
     if (engDefnLoadedEvent!=null) 
     { 
      engDefnLoadedEvent(this,data); 
     } 
    } 


    public void loadEngDefn() 
    { 
     if (this.engDefinition=="") 
     { 
    //   wb1 = new WebBrowser(); 
      wb1.ScriptErrorsSuppressed = true; 
      wb1.Url = new Uri(this.engUrl); 
     } 
     else 
     { 
      if (engDefnLoadedEvent!=null) 
      { 
       engDefnLoadedEvent(this, new EventArgs()); 
      } 
     } 

    } 


    public void loadHinDefn() { 
     if (this.hindiDef=="") 
     { 
    //  wb2 = new WebBrowser(); 
      wb2.ScriptErrorsSuppressed = true; 
      wb2.Url = new Uri(this.hindiUrl); 
     } 
     else 
     { 
      if (HindiDefLoadedEvent!=null) 
      { 
       HindiDefLoadedEvent(this, new EventArgs()); 
      } 
     } 

    } 
    [NonSerialized] 
    HtmlDocument hd; 

    void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 

      if (((WebBrowser)sender).ReadyState == WebBrowserReadyState.Complete) 
      { 
       hd = ((WebBrowser)sender).Document; 
       if (e.Url.ToString() == this.hindiUrl) 
       { 
        parsePage(hd.GetElementById("maint"), "hindi"); 
        ((WebBrowser)sender).DocumentCompleted -= wb_DocumentCompleted; 
        sender = null; 
       } 
       else 
       { 
        parsePage(hd.GetElementById("entryPageContent"), "eng"); 
        ((WebBrowser)sender).DocumentCompleted -= wb_DocumentCompleted; 
        sender = null; 
       } 

      }     
    } 

    private void parsePage(HtmlElement hd, string lan) 
    { 
     HtmlElementCollection he; 
     if (lan == "eng") 
     { 
      he = hd.GetElementsByTagName("section"); 
      foreach (HtmlElement item in he) 
      { 
       this.engDefinition += item.InnerHtml + "<br>"; 
      } 
      flagE = true; 
      engDefnLoadedEvent(this, new EventArgs()); 
      wb1 = null; 
      wb1.Dispose(); 
      return; 
     } 
     else 
     { 
      he = hd.GetElementsByTagName("div"); 
      foreach (HtmlElement item in he) 
      { 
       if (item.GetAttribute("itemprop") == "itemListElement") 
       { 
        this.hindiDef += item.GetElementsByTagName("div")[0].InnerHtml + "<br>"; 
       } 
      } 
      flagH = true; 
      HindiDefLoadedEvent(this,new EventArgs()); 
      wb2 = null; 
      wb2.Dispose(); 
      return; 
     } 
    } 

问:如何删除此内存泄漏问题?

样品PIC Memory Snap After two 4-5 queries.

后查询25个字。

DeadLock

+1

你有没有简介你的应用程序?所使用的内存量是否与查询数成线性比例关系? –

回答

0

首先,我想指出的是,仅仅因为你的应用程序使用300 - 400 MB的内存并不一定意味着你有内存泄漏。只有当内存不断增加,每个请求的页面,并永远不会释放你有泄漏。

其次,为了诊断问题,您需要运行内存分析器。如果您使用的是Visual Studio的Premium或Ultimate版本,则它具有内存配置文件功能。如果不是,您可以使用RedGate Memory Profile(14天免费试用版)或类似软件。

我还会补充一点,在.NET中泄漏的最常见原因是使用短活件对象作为观察者/处理程序附加到由长寿命对象引发的事件。

+0

不幸的是它的内存泄漏因为我尝试了我的应用程序直到1100 MB的内存使用。每次查询后它都会不断增加。 :( – Arpit

0
在您的Word类的构造函数

那么你有下面的代码:

wb1 = new WebBrowser(); 
wb2=new WebBrowser(); 

web浏览器类不被实例化一些当地的IE version.My猜测的网页浏览功能是web浏览器的存在IE的一部分它有很高的内存消耗。所以想象你为每个单词实例化了2个WebBrowser对象。你可以为你的WebBrowser对象使用一个池系统,但是我会用WebClient对象替换那些行为这是一次性的。

P.S.垃圾收集器系统是一个使用GC.Collect();的微调系统,就像在您的代码上使用大锤。

+0

其实我是维护一个全局的单词对象,每次我只是改变全局单词对象的URL。 – Arpit

+1

鉴于你正在迭代你的历史中的一个'Word'集合,你确定吗? –

+0

这就是我想也是普雷斯顿,它似乎并不只是一个全球性的单词对象 – kodeslacker

相关问题