开发者社区> 狗子2018> 正文

c#+wpf项目性能优化之OutOfMemoryException解密

简介: 近期,使用c#+wpf开发的软件准备正式投入使用了,使用前进行了大量的测试,测试后发现了一些问题,其中最让人头疼的就是软件的性能问题(稳定性)。 这里的稳定性具体表现在机器的cpu占有率和内存使用情况: 1,CPU占用率节节攀升。
+关注继续查看

近期,使用c#+wpf开发的软件准备正式投入使用了,使用前进行了大量的测试,测试后发现了一些问题,其中最让人头疼的就是软件的性能问题(稳定性)。

这里的稳定性具体表现在机器的cpu占有率和内存使用情况:

1,CPU占用率节节攀升。

2,可用内存越来越少,最后爆OutOfMemoryException。

这两点足以影响软件的应用,一日不除,终日不得安宁!

发现问题后,多方搜寻资料,最终问题解决,这里做一些记录,一来分享给各路开发者,二来记录以备自己查看。

导致cpu占用率高:

 

1.是否有textbox的不断循环中取值,赋值以及ScrollToend,解决方法:将TextBox控件换成ListBox,这样是一行一行插入

2.搜索代码中是否有while死循环。解决方法:优化代码,删掉死循环,while循环中可以加入

   system.application.doevent();

   thread.sleep(100);

我本人的项目中就是因为存在大量对textBox的操作,而导致的,我将TextBox控件换成ListBox后CPU占用率明显下降。

 

导致可用内存越来越少的原因:

1.界面上很多动画切换效果,如:gif动画的帧切换,解决方法gif动画暂用大量内存,需要及时释放,尽量少用gif

2.界面上显示很多图片,图片资源未回收,解决方法:释放图片资源

     一:将Image类转换成Bitmap类
    System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);
    System.Drawing.Image bmp = new System.Drawing.Bitmap(img);
    img.Dispose();
    然后使用 bmp作为PictureBox的图片源
    二:从流中读取
    FileStream fileStream = new FileStream("文件名", FileMode.Open, FileAccess.Read);
    pictureBox1.Image = Image.FromStream(fileStream);
    fileStream.Close();
    fileStream.Dispose(); 

3.非托管资源及其内存回收,对可能多次调用的类,应该严格按照“清理模式”格式书写,保证类资源被及时释放:

    标准的清理模式(~dispose)写法:

    

MyClass:IDisposable
    {
        private bool disposed = false;
        ~MyClass()
        {
            Dispose(false);
        }
    
        public void Dispose()
        {
           Dispose(true);
           GC.SuppressFinalize(this);
        }
       
       private void Dispose(bool disposing)
       {
          if(disposed == false)
          {
               if(disposing == true)
               {
                  // 释托管代码
                  ......
               }
              // 释非代码
             ......
          }
          disposed = true;
       }
   }
View Code

4.确保万无一失,使用using(){}来引用类,使用方法:

    using(classA a =new classA()){
      //用完后就释放
    }
    只有继承:IDisposable的类才能用using

5.网上给出了一个强制回收内存的方法,貌似看起来内存占用是减少了,一调用内存就降下来。先别高兴太早,这其实是伪释放,只为暂时解决内存大量泄露导致系统崩溃而急需解决的情况。
具体原因:http://blog.sina.com.cn/s/blog_49f8960e0100081x.html,关键字:将物理内存转到虚拟内存,涉及磁盘读写。

ps:为了好看一点,我们可以加进去!

  具体代码:

[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
/// <summary>
/// 释放内存
/// </summary>
public static void ClearMemory()
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
    {
 SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
    }
}
View Code

6.最后的杀手锏,查看软件中是否调用过什么开源插件,升级插件到稳定版本。

  本人项目中就遇到这个问题,本人项目中使用了cefsharp插件,期初使用的是低版本,这次索性升级到最新版本,然后将.net框架也升级了(其中也遇到了一些问题,NuGet资源下载慢,.net升级后与原来的部分库文件不匹配等,打怪升级各个击破吧!),然后就奇迹的解决了问题,所以最后结论就是需要不断的尝试和改进,寻找一切可能的突破口来解决问题。

 

-------------------------------分隔线-----------------------

写在最后:对于c#程序的性能优化工作,我们可以多实用工具,工欲善其事必先利其器,如:

1.vs自带的性能分析工具:

分析->诊断,按照指导操作。

2.ANTS Performance Profiler和ANTS Memory Profiler,分别用来做性能分析和内存占用分析,讲具体操作方法自行百度,能够准确找到性能瓶颈所在。

3.DotTrace,和上面的工具类似。

4.可以安装.net reflection来查看dll具体方法(可能会导致vs无法调试)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java单体应用 - 项目实战(后台)
本文继续以 「[Java单体应用 - 常用框架 - MyBatis] 章节所使用的案例项目 iot-cloud2 为基础进行讲解。
386 0
C++第2周(春)项目2 有序的结构体数组
课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759 【项目2-有序的结构体数组】使用同项目1相同的结构体类型,在main函数中已经对结构体数组进行了初始化,请完成相关函数的定义,实现main函数中要求的功能。 struct Student //同项目1 { …… }; void cal
1112 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
19753 0
实操 | 如何通过 SOFALookout & Prometheus 监控 SpringBoot 项目
SOFA (Scalable Open Financial Architecture ) 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,在蚂蚁金服内部经过了将近 10 年的实践以及发展。
516 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18018 0
Spring Boot 项目如何做性能监控?
Spring Boot特别适合团队构建各种可快速迭代的微服务,同时为了减少程序本身监控系统的开发量,Spring Boot 提供了 actuator 模块,可以很方便的对你的 Spring Boot 程序做监控。
31 0
+关注
狗子2018
web开发
24
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载