• C# GC Finalizer IDispseable,.Net的垃圾回收机制


    1.GC只能回收堆里的托管资源

    2.GC 回收,"代"的概念

    .net 托管资源分三代,代数越大 资源的生命周期越长.

    0 代 和1代的资源比较少可以比较频率的回收, 回收2代以上差不多等于对整个应用程序的堆进行遍历了,比较不适合频繁的回收.

    GC.Collection() 对所有代的资源进行遍历 回收, GC.collection(1) 则是只回收0代和1代

    3.GC回收的过程

    对没有被引用的堆资源标记成可回收,对已标记成可回收的资源进行回收,

    对于有析构函数的资源判断是否已执行过析构函数,如果没有执行过,对其进行复活.如果有执行过了,标记成可回收,下次GC才回收.

    回收完后堆中的资源压缩空间,可以理解成  垃圾箱中的一部份垃圾被灭霸消灭了,把垃圾箱重新踩实,堆中的地址发生了变化,栈,静态引用,CPU寄存器引用的指针更新地址

    4.Finalization

    在GC回收的过程中讲到析构函数,所以有必要补充的说一下什么是析构函数

    publci class MyClass
    
    {
    
        ~MyClass()
    
        {
                //在下就是析构函数
        }
    
    }

    析构函数的作用是用来释放非托管资源.C++资源 , stream ,ect..但是它只能被GC调用,回收的时机是不确定的.

    5 IDispseable 接口

    如果只是实现了析构函数,那么回收的时间不能确定,性能相对来说比较差.所以.Net给出另一个答案,IDispseable接口

    此接口中只有一个方法 void Dispose();

    void Dispose()
    {
        //释放非托管资源

    GC.SuppressFinalize(this); //GC在回收时将不再调用此类的析构函数 }

    用这个方法释放非托管之后还要执行这行代码 .

    Dispose和Finalizeter  可以一起使用.MSDN上推荐的实现如下

     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace MemoryTest.Model
     9 {
    10     public class MyClass : IDisposable
    11     {
    12         #region 变量声明
    13         // 指向外部非托管资源
    14         private IntPtr handle;
    15         // 此类使用的其它托管资源.
    16         private Component Components;
    17         // 跟踪是否调用.Dispose方法,标识位,控制垃圾收集器的行为
    18         private bool isDisposed = false; 
    19         #endregion
    20 
    21         #region Finalizer
    22         ~MyClass()
    23         {
    24             Dispose(false);
    25         }
    26         #endregion
    27 
    28         #region IDispseable 接口实现
    29         public void Dispose()
    30         {
    31             Dispose(true);
    32             GC.SuppressFinalize(this);
    33         }
    34         #endregion
    35 
    36         #region 释放方法
    37         /// <summary>
    38         /// 释放非托管资源
    39         /// </summary>
    40         /// <param name="isManual">手动调用为true,系统调用为flase</param>
    41         protected virtual void Dispose(bool isManual)
    42         {
    43             if (isDisposed) return;
    44             isDisposed = true;
    45             //释放非托管资源
    46             handle = IntPtr.Zero;
    47 
    48             if (isManual)
    49             {
    50                 //释放其他disose对象
    51                 Components?.Dispose();
    52             }
    53 
    54         } 
    55         #endregion
    56     }
    57 }
  • 相关阅读:
    【002】有符号数据传递给无符号变量
    C++第二课 数据类型和常变量
    【001】冒泡排序
    iOS中为网站添加图标到主屏幕以及增加启动画面
    _stdcall,_cdecl区别
    解决表格里面使用text-overflow后依旧不能隐藏超出的文本
    windows7 64位下运行 regsvr32 注册ocx或者dll的方法
    在sqlite中使用索引
    ASP中 Request.Form中文乱码的解决方法
    html——标签基础
  • 原文地址:https://www.cnblogs.com/nocanstillbb/p/10282229.html
Copyright © 2020-2023  润新知