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无法调试)

目录
相关文章
|
1天前
|
编解码 C# 数据库
C# + WPF 音频播放器 界面优雅,体验良好
【9月更文挑战第18天】这是一个用 C# 和 WPF 实现的音频播放器示例,界面简洁美观,功能丰富。设计包括播放/暂停按钮、进度条、音量控制滑块、歌曲列表和专辑封面显示。功能实现涵盖音频播放、进度条控制、音量调节及歌曲列表管理。通过响应式设计、动画效果、快捷键支持和错误处理,提升用户体验。可根据需求扩展更多功能。
|
14天前
|
JSON 测试技术 C#
C#/.NET/.NET Core优秀项目框架推荐榜单
C#/.NET/.NET Core优秀项目框架推荐榜单
|
1月前
|
C# Windows
C# 创建 Windows Service 项目
C# 创建 Windows Service 项目
29 1
|
21天前
|
C# UED 开发者
WPF与性能优化:掌握这些核心技巧,让你的应用从卡顿到丝滑,彻底告别延迟,实现响应速度质的飞跃——从布局到动画全面剖析与实例演示
【8月更文挑战第31天】本文通过对比优化前后的方法,详细探讨了提升WPF应用响应速度的策略。文章首先分析了常见的性能瓶颈,如复杂的XAML布局、耗时的事件处理、不当的数据绑定及繁重的动画效果。接着,通过具体示例展示了如何简化XAML结构、使用后台线程处理事件、调整数据绑定设置以及利用DirectX优化动画,从而有效提升应用性能。通过这些优化措施,WPF应用将更加流畅,用户体验也将得到显著改善。
48 0
|
21天前
|
持续交付 C# 敏捷开发
“敏捷之道:揭秘WPF项目中的快速迭代与持续交付——从需求管理到自动化测试,打造高效开发流程的全方位指南”
【8月更文挑战第31天】敏捷开发是一种注重快速迭代和持续交付的软件开发方法,通过短周期开发提高产品质量并快速响应变化。本文通过问题解答形式,探讨在Windows Presentation Foundation(WPF)项目中应用敏捷开发的最佳实践,涵盖需求管理、版本控制、自动化测试及持续集成等方面,并通过具体示例代码展示其实施过程,帮助团队提升代码质量和开发效率。
37 0
|
21天前
|
C# 开发者 Windows
勇敢迈出第一步:手把手教你如何在WPF开源项目中贡献你的第一行代码,从选择项目到提交PR的全过程解析与实战技巧分享
【8月更文挑战第31天】本文指导您如何在Windows Presentation Foundation(WPF)相关的开源项目中贡献代码。无论您是初学者还是有经验的开发者,参与这类项目都能加深对WPF框架的理解并拓展职业履历。文章推荐了一些适合入门的项目如MvvmLight和MahApps.Metro,并详细介绍了从选择项目、设置开发环境到提交代码的全过程。通过具体示例,如添加按钮点击事件处理程序,帮助您迈出第一步。此外,还强调了提交Pull Request时保持专业沟通的重要性。参与开源不仅能提升技能,还能促进社区交流。
28 0
|
21天前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
59 0
|
21天前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
53 0
|
21天前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
36 0
|
1月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
31 0