• C#内存释放(垃圾回收)


    C#内存释放(垃圾回收)

    问题背景----

    今天写了个很小的程序,程序的功能仅仅是截图,但是如果长时间开启并截图的时候,程序会变的很大,从刚开始的运行在任务管理器中只有十几K大小,运行一段时间后在任务管理器中看到程序可以达到1G或2G甚至更大;最初想到的是所有的截图都保存在内存中,没有释放造成的。去检查代码,发现程序中已经使用GC.Collect();但是为什么程序还是会一直增加呢?由于程序中逻辑判断等比较多,不方便跟踪及查找。所以我自己单独写了个测试程序,去看看调用GC.Collect();释放的问题?

    测试环境----

    首先准备一个对象(由于程序中使用了一些静态变量),所以准备的对象如下:

    复制代码

    public class CountObject
        {
            public static int Count = 0;
            public CountObject()
            {
                Count++;
            }
    
            ~CountObject()
            {
                Count--;
            }
        }

    复制代码

    程序很简单,只有一个静态的计数变量。下面在看看主程序:

    复制代码

     1 static void Main(string[] args)
     2         {
     3             CountObject obj;
     4             for (int i = 0; i < 5; i++)
     5             {
     6                 obj = new CountObject();
     7                 //obj = null; // 这一步,只是为了更清晰些验证引用的对象是否释放!
     8                 GC.Collect();
     9 
    10             }
    11             //GC.Collect();
    12             //GC.WaitForPendingFinalizers();
    13 
    14             // Count不会是1,因为Finalizer不会马上被触发,要等到有一次回收操作(GC.Collect())后才会被触发。 GC.Collect();GC.WaitForPendingFinalizers();
    15             Console.WriteLine(CountObject.Count);
    16             Console.ReadKey();
    17         }

    复制代码

    程序也比较简单,我做了如下测试:

    1)使用以上程序运行,发现15行会输出5,说明我们调用了GC.Collect();但程序并没有执行释放,因为查GC的官方解释,是不确定的某个时刻进行回收。

    2)把循环每次增大5个。当循环增加到125的时候,多次执行后发现,我本机测试,在第15行的输出是1或125,当增加到10000,每次都输出1,说明符合官方解释;

    根据以上代码测试知道,当循环5次的时候,GC并不会立即执行,所以当执行5次循环的时候第8行没起作用。既然不起作用,我们把他注释暂时不用,把11和12行开启。

    3)把地8行注释,11,12行开启,执行5次循环,发现15行输出1,多次执行结果相同。

    4)再把11行注释,12行开启,执行5次循环,发现15行输出5,多次执行结果相同。

    5)再把12行注释,11行开启,执行5次循环,发现15行输出5,多次执行结果相同。

    根据4和5的才测试可以看到,当少量的循环时Finalizer不会马上被触发,要等到有一次回收操作(GC.Collect())执行后才会被触发。所以我们可以显式调用 GC.Collect();GC.WaitForPendingFinalizers();这两行代码进行强制回收的执行。

    6)验证,把第7行开启,执行测试第15行为0,说明对象如果没有任何的引用则可以强制回收。

    以上是本人的一些测试,如果你还有更好的想法,可以提出一起讨论;

    版权归个人所有,转载请注明出处;

    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我

    如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,求打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【Jack_孟】!

    分类: C#

  • 相关阅读:
    final方法修饰继承问题
    日期比较
    子类继承父类,初始化以及方法调用顺序
    linux机器上实现占用固定cpu使用率,并将程序绑定到固定cpu上
    【译】Rust宏:教程与示例(二)
    【译】Rust宏:教程与示例(一)
    【译】Async/Await(五)—— Executors and Wakers
    【译】Async/Await(四)—— Pinning
    通过工具dumpbin.exe快速查看dll的编译版本是Release还是Debug
    【常用操作】ubuntu部署说明
  • 原文地址:https://www.cnblogs.com/grj001/p/12225159.html
Copyright © 2020-2023  润新知