C# 为什么这个应用程序占用了这么多内存?
所以我的问题是,我创建了一个应用程序供我个人使用,它从一些网站获取html页面,经过一些修改后,将其显示在web浏览器中。每件事都很顺利,但让我不安的是它占用的记忆。查询3-4个术语后,内存使用量达到大约300-400 mb 应用程序中的一些相关代码是C# 为什么这个应用程序占用了这么多内存?,c#,memory-leaks,webbrowser-control,C#,Memory Leaks,Webbrowser Control,所以我的问题是,我创建了一个应用程序供我个人使用,它从一些网站获取html页面,经过一些修改后,将其显示在web浏览器中。每件事都很顺利,但让我不安的是它占用的记忆。查询3-4个术语后,内存使用量达到大约300-400 mb 应用程序中的一些相关代码是 void sentenceBox_Navigated(object sender, WebBrowserNavigatedEventArgs e) { GC.Collect(); }
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;
}
}
公共字(字符串q)
{
wb1=新的WebBrowser();
wb2=新的WebBrowser();
英语单词=q;
hindiDef=“”;
engDefinition=“”;
鞭毛=假;
flagH=假;
英语=”http://oxforddictionaries.com/definition/english/“+q+”?q=“+q;
印度语=”http://dict.hinkhoj.com/hindi-dictionary.php?word=“+q;
wb1.DocumentCompleted+=新的WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
wb2.DocumentCompleted+=新的WebBrowserDocumentCompletedEventHandler(wb\U DocumentCompleted);
}
public delegate void engdenfloaded(单词发送者、事件参数数据);
公共活动工程师;
受保护的无效OnnegDefnloadCompleted(Word发件人、EventArgs数据)
{
if(engdefnloadevent!=null)
{
Engdefnloadevent(此,数据);
}
}
公共void loadEngDefn()
{
if(this.engDefinition==“”)
{
//wb1=新的WebBrowser();
wb1.ScriptErrorsSuppressed=真;
wb1.Url=新Uri(this.engUrl);
}
其他的
{
if(engdefnloadevent!=null)
{
engDefnLoadedEvent(这是新的EventArgs());
}
}
}
公共void loadHinDefn(){
if(this.hindiDef==“”)
{
//wb2=新的WebBrowser();
wb2.ScriptErrorsSuppressed=真;
wb2.Url=新Uri(this.hindiUrl);
}
其他的
{
如果(HindideFloadevent!=null)
{
HindideFloadevent(这是新的EventArgs());
}
}
}
[非串行化]
HtmlDocument hd;
作废wb_DocumentCompleted(对象发送方,WebBrowserDocumentCompletedEventArgs e)
{
if(((WebBrowser)发送方.ReadyState==WebBrowserReadyState.Complete)
{
hd=((WebBrowser)发送者)。文档;
if(e.Url.ToString()==this.hindiUrl)
{
parsePage(hd.GetElementById(“maint”),“印地语”);
((WebBrowser)发件人)。DocumentCompleted-=wb_DocumentCompleted;
发送方=空;
}
其他的
{
parsePage(hd.GetElementById(“entryPageContent”),“eng”);
((WebBrowser)发件人)。DocumentCompleted-=wb_DocumentCompleted;
发送方=空;
}
}
}
专用页面(HtmleElement hd、字符串lan)
{
HtmlElementCollection he;
如果(局域网==“英语”)
{
he=hd.GetElementsByTagName(“节”);
foreach(he中的HtmlElement项)
{
this.engDefinition+=item.InnerHtml+“
”;
}
鞭毛=真;
engDefnLoadedEvent(这是新的EventArgs());
wb1=null;
wb1.Dispose();
返回;
}
其他的
{
he=hd.GetElementsByTagName(“div”);
foreach(he中的HtmlElement项)
{
if(item.GetAttribute(“itemprop”)=“itemListElement”)
{
this.hindiDef+=item.GetElementsByTagName(“div”)[0].InnerHtml+“
”;
}
}
flagH=真;
HindideFloadevent(这是新的EventArgs());
wb2=null;
wb2.Dispose();
返回;
}
}
问题:如何消除此内存泄漏问题
样本图片
查询后25个单词
首先,我想指出,仅仅因为您的应用程序使用了300-400 MB的内存,并不一定意味着您有内存泄漏。只有当内存随着每个请求的页面不断增加且从未释放时,才会发生泄漏 其次,为了诊断问题,您需要运行内存分析器。如果您使用的是Visual Studio的高级版或终极版,它具有内存配置文件功能。如果没有,您可以使用(14天免费试用)或类似软件
我还想补充一点,导致.NET泄漏的最常见原因是使用事件,其中一个短期对象将自身作为观察者/处理程序连接到一个长期对象引发的事件。在Word类的构造函数中,您有以下代码:
wb1 = new WebBrowser();
wb2=new WebBrowser();
WebBrowser类的作用是实例化本地IE版本的一些web浏览功能。我猜WebBrowser是IE的一部分,它具有很高的内存消耗。因此,假设您为每个单词实例化2个WebBrowser对象。您可以为WebBrowser对象使用池系统,但是我会用一个WebClient对象来代替这些行为,它是一次性的
另外,垃圾收集器系统是一个经过微调的系统,使用
GC.Collect()代码>这就像在代码上使用大锤一样。不幸的是,这是内存泄漏,因为我一直尝试我的应用程序,直到使用1100 mb内存。每次查询后,它都会不断增加:(你分析过你的应用程序吗?使用的内存量是否与查询数成线性关系?实际上,我正在维护一个全局word对象,每次我只是更改全局word对象的url。考虑到你在历史记录中迭代一组word
,你确定吗?这也是我认为的P。)reston,它似乎不是只有一个全局word对象word w=new word()
我只使用了它