C#中WPF内存回收与释放LierdaCracker的实现

使用wpf程序常常会出现一个问题,那就是内存占用过高,使用wpf的程序功能越复杂往往用着用着内存就本着90往上去了。

一方面wpf本身是一个ui框架,对图像以及界面的渲染虽然提高了软件的美观性,但实际使用过程中调用和消耗了大量的内存来进行协同处理;
另一方面这些调用的内存的确在使用完成之后并没有进行主动的释放或者是只是自动释放了一部分,即对于托管资源通过GC自动清理回收。对于非托管资源,通过代码调用手动进行清除,再由GC回收。例如流,数据库连接,网络连接等,所以就需要我们主动定时的对内存进行回收释放的处理。

在这里非常推荐使用LierdaCracker

一.可以使用nuget管理安装Lierda.WPFHelper包,在项目的App.xaml.cs中的Application_Startup方法里实例化并调用cracker方法直接使用

   LierdaCracker cracker = new LierdaCracker();
   cracker.Cracker();

二.自己实现LierdaCracker类

提到C#资源和内存回收肯定少不了GC垃圾回收机制,托管堆上的内存由GC全权负责, 值引用的在栈上的内存会随着栈空间的消亡而自动消失。

GC.Collect();
GC.WaitForPendingFinalizers();

此方法强制对所有代进行即时垃圾回收!

当应用程序代码中某个确定的点上使用的内存量大量减少时,在这种情况下使用 GC.Collect 方法可能比较合适。而GC.WaitForPendingFinalizers则是提供收集完成前的等待。

另外一个非常重要的系统api在释放内存的时候也是非常重要的
SetProcessWorkingSetSize,使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存。当应用程序被闲置或系统内存太低时,操作系统会自动调用这个机制来设置应用程序的内存。应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放。

事实上,使用该函数并不能提高什么性能,也不会真的节省内存。
因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有操作请求时,这些内存又会被重新占用。如果你强制使用该方法来 设置程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换。

BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);

将 2个 SIZE_T 参数设置为 -1 ,即可以使进程使用的内存交换到虚拟内存,只保留一小部分代码,它是windowsNT的api 所以使用的使用需要加上平台条件。

 if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);

综合下来LierdaCracker类为

 public class LierdaCracker
 {
     [DllImport("kernel32.dll")]
     private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);

     private void FlushMemory()
     {
          GC.Collect();
          GC.WaitForPendingFinalizers();
          if (Environment.OSVersion.Platform == PlatformID.Win32NT)
              SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
      }

      public void Cracker(int sleepSpan = 50)
      {
           _ = Task.Factory.StartNew(delegate
           {
               while (true)
               {
                   try
                   {
                       SetDate();
                       FlushMemory();
                       Thread.Sleep(TimeSpan.FromSeconds((double)sleepSpan));
                   }
                   catch { }
               }
           });
       }

 }

到此这篇关于C#中WPF内存回收与释放LierdaCracker的实现的文章就介绍到这了,更多相关C# WPF内存回收与释放 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#字符串内存分配与驻留池学习分享

    刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例.如下: 复制代码 代码如下: String s1 ="Hello";String s2 ="Hello";                       //s2和s1的实际值都是Hellobool same = (object) s1 == (object) s2;//这里比较s1.s2是否引用了同一个对象实例//所

  • C#使用文件流FileStream和内存流MemoryStream操作底层字节数组byte[]

    一.Stream类概述 在.NET Framework中,文件和流是有区别的. 文件是存储在磁盘上的数据集,它具有名称和相应的路径.当打开一个文件并对其进行读/写时,该文件就称为流(stream). 但是,流不仅仅是指打开的磁盘文件,还可以是网络数据..Net Framework允许在内存中创建流.此外,在控制台应用程序中,键盘输入和文本显示都是流. 1. Stream类 Stream类是所有流的抽象基类. Stream类的主要属性有CanRead.CanWrite(是否支持读取写入).CanS

  • C#使用stackalloc分配堆栈内存和非托管类型详解

    目录 stackalloc 表达式 stackalloc 分配 System.Span<T> 或 System.ReadOnlySpan<T> 类型 stackalloc 分配 指针类型 stackalloc分配内存的注意点 非托管类型 Unmanaged type stackalloc 表达式 stackalloc表达式在栈(stack)上分配内存块. 在方法执行期间创建的栈中分配的内存块会在方法返回时自动丢弃.不能显式释放使用 stackalloc 分配的内存.stackall

  • C#集合本质之堆栈的用法详解

    在"了解集合本质必须要知晓的概念-链表"中,我们了解了链表的概念和种类,并且模拟了一个单向链表.本篇体验的堆栈是约束版的链表,只能在栈顶接收新节点和释放节点. 堆栈的主要操作是压栈和出栈.压栈是将新节点放在栈顶,出栈是从栈顶取出一个节点,返回新弹出节点的数据项.堆栈也称为后进先出的数据结构. 接着上一篇,写一个派生于List的类来模拟堆栈的压栈和出栈. namespace LinkedListLibrary { public class StackInheritance : List

  • C#中的队列Queue<T>与堆栈Stack<T>

    一.概述: Queue<T>队列,对象的先进先出集合(“FIFO”).Stack<T>栈,对象的后进先出集合(”LIFO”). Queue<T>.Stack<T>类似于List<T>,但 Queue<T>没有IList<T>,所以不能用索引访问队列.也没有实现ICollection<T>,无Add,Remove等方法. 二.操作 1.入队列:Enqueue() Queue<string> nums

  • C#内存管理CLR深入讲解(上篇)

    半年之前,PM让我在部门内部进行一次关于“内存泄露”的专题分享,我为此准备了一份PPT.今天无意中将其翻出来,觉得里面提到的关于CLR下关于内存管理部分的内存还有点意思.为此,今天按照PPT的内容写了一篇文章.本篇文章不会在讨论那些我们熟悉的话题,比如“值类型引用类型具有怎样的区别?”.“垃圾回收分为几个步骤?”.“Finalizer和Dispose有何不同”.等等,而是讨论一些不同的内容.整篇文章分上下两篇,上篇主要谈论的是“程序集(Assembly)和应用程序域(AppDomain)”.也许

  • C#中WPF内存回收与释放LierdaCracker的实现

    使用wpf程序常常会出现一个问题,那就是内存占用过高,使用wpf的程序功能越复杂往往用着用着内存就本着90往上去了. 一方面wpf本身是一个ui框架,对图像以及界面的渲染虽然提高了软件的美观性,但实际使用过程中调用和消耗了大量的内存来进行协同处理;另一方面这些调用的内存的确在使用完成之后并没有进行主动的释放或者是只是自动释放了一部分,即对于托管资源通过GC自动清理回收.对于非托管资源,通过代码调用手动进行清除,再由GC回收.例如流,数据库连接,网络连接等,所以就需要我们主动定时的对内存进行回收释

  • Android操作系统之内存回收策略

    Android 是一款基于 Linux 内核,面向移动终端的操作系统.为适应其作为移动平台操作系统的特殊需要,谷歌对其做了特别的设计与优化,使应用程序关闭但不退出,并由操作系统进行进程的回收管理.本文在 Application Framework 与 Linux 内核两个层次上,以进程为粒度,对 Android 操作系统的进程资源回收机制进行了剖析.读者可以从本文获得对 Android 应用程序的生存周期的进一步理解,从而更加合理.高效地构建应用程序. Android 操作系统中的内存回收可分为

  • 解析PHP中的内存管理,PHP动态分配和释放内存

    摘要 内存管理对于长期运行的程序,例如服务器守护程序,是相当重要的影响:因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要.本文将重点探讨PHP的内存管理问题. 一. 内存在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = 'hello world '; ?>"即可,并且该字符串能够被自由地修改.拷贝和移动.而在C语言中,尽管你能够编写例如"char *str = "hello world ";&qu

  • JS类库Bindows1.3中的内存释放方式分析

    我在前段时间介绍过IE中JavaScript脚本Memory Leak的问题,后来在几位热心网友的讨论下,基本认可了内存泄露的事实和原理.在小规模的测试case下,本来都达到了基本避免IE中脚本的ML问题.可是近来发现只以"仔细"来防止IE中脚本ML似乎是非常困难的一件事情,难道开始的讨论有错误吗? 何谓"仔细"呢?就是说在有对象相互引用的时候,在对象丢弃时(不一定是页面refresh)断开彼此的引用链,特别是脚本中创建的对象和DHTML中的对象间的引用:清除HTM

  • 理解Java中的内存泄露及解决方法示例

    本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助. Java内存管理机制 在C++ 语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存的泄露. Java 语言对内存管理做了自己的优化,这就是垃圾回收机制. Java 的几乎所有内存对象都是在堆内存上分配(基本数据类型

  • JVM中堆内存和栈内存的区别

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用. 堆内存用于存放由new创建的对象和数组.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中

  • 浅谈Java编程中的内存泄露情况

    必须先要了解的 1.c/c++是程序员自己管理内存,Java内存是由GC自动回收的. 我虽然不是很熟悉C++,不过这个应该没有犯常识性错误吧. 2.什么是内存泄露? 内存泄露是指系统中存在无法回收的内存,有时候会造成内存不足或系统崩溃. 在C/C++中分配了内存不释放的情况就是内存泄露. 3.Java存在内存泄露 我们必须先承认这个,才可以接着讨论.虽然Java存在内存泄露,但是基本上不用很关心它,特别是那些对代码本身就不讲究的就更不要去关心这个了. Java中的内存泄露当然是指:存在无用但是垃

  • 深入解析C语言中的内存分配相关问题

    C内存分配区域 程序代码区 存放函数体的二进制代码 全局数据区 全局变量和静态变量的存储是放在一起的.初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域.常量数据存放在另一个区域里.这些数据在程序结束后由系统释放.我们所说的BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称 栈区 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似

  • 浅析Node.js中的内存泄漏问题

    这篇文章是由Mozilla的Identity团队带来的 A Node.JS Holiday Season系列文章的首篇,该团队上个月发布了 Persona的第一个测试版本.在开发Persona时我们构建了一系列的工具,包括了从调试,到本地化,到依赖管理以及更多的方面.在这一系列的文章中我们将与社区分享我们的经验和这些工具,这对任何想用node.js建立一个高可用性服务的人都很有用.我们希望您能喜欢这些文章,并期待看到您的想法和贡献. 我们将从一篇关于Node.js的实质性问题:内存泄漏的主题文章

  • 简单讲解Lua中的垃圾回收机制

    Lua使用基于被内置在Lua某些算法的垃圾收集自动内存管理.可以自动内存管理的结果,作为一个开发者: 没有必要担心的对象分配内存. 无需释放他们时,不再需要可将其设置为nil. Lua使用运行不时收集死的对象时,不再从Lua程序中访问垃圾收集器. 所有对象,包括表,用户数据,函数,线程,字符串等受自动内存管理. Lua使用增量标记和使用两个数字来控制其垃圾回收周期即垃圾收集暂停和垃圾收集器的步骤事半功倍清除收集器.这些值是在百分比和100的值是常等于1. 垃圾收集暂停 垃圾收集停顿被用于控制多长

随机推荐