美文网首页
C# GC与内存管理

C# GC与内存管理

作者: CodeVin | 来源:发表于2019-03-03 18:30 被阅读0次

GC即Garbage Collection,垃圾回收的意思。C#的垃圾回收器Garbage Collector会跟踪并回收托管内存中分配的对象。垃圾回收器会周期性地执行垃圾回收,回收托管内存中没有被有效引用的对象。

我们知道C#中的变量分为值类型和引用类型。值类型的变量存储在栈(stack)上,在作用域结束时自动释放,并不需要GC回收。引用类型的变量存储在堆(heap)上,在.NET 这种托管环境下,堆由CLR (公共语言运行库Common Language Runtime)进行管理,所以又称为“托管堆(managed heap)”。大部分对象都是托管资源,GC能够自动回收托管堆上的托管资源。但是GC不能自动回收非托管资源,常见的一般有操作系统资源对象,如:网络连接,文件流,数据库连接等。所以我们需要编写回收非托管资源的代码。

释放非托管资源的正确方式,是为类型实现IDisposable接口的Dispose方法,当你需要释放类型的资源的时候,应该显式的调用Dipose方法。这里还有一个C#的语法糖,就是使用using程序块,在离开using程序块的时候,CLR会自动调用类型所创建对象的Dipose方法。如在Unity3D中使用WWW并释放网络连接资源的例子:

public class ExampleClass : MonoBehaviour
{
    public string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
    IEnumerator Start()
    {
        using (WWW www = new WWW(url))
        {
            yield return www;
            Renderer renderer = GetComponent<Renderer>();
            renderer.material.mainTexture = www.texture;
        }
    }
}

Dispose的实现示例如下:

public class Foo : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                //释放托管资源
            }
            // 释放非托管资源
            disposed = true;
        }
    }

    //既释放托管资源,又释放非托管资源
    public void Dispose()
    {
        Dispose(true);
        //将对象从垃圾回收器链表中移除,      
        //从而在垃圾回收器工作时,只回收托管资源,而不执行对象的析构函数
        GC.SuppressFinalize(this);
    }
    
    //以防开发人员忘记调用Dispose
    ~Foo()
    {
        Dispose(false);
    }
}



一些额外的Tips

  • String与StringBuilder

String类型的变量是不可变的,当一个String类型的变量被初始化以后,任何对它的修改都会创建一个新的对象,当对一个字符串有频繁修改的需求时,会影响性能,而StringBuilder则没有这个问题。因此遇到上述情况用StringBuilder更合适。

  • Array,ArrayList和List

数组Array

优点:

  1. 数组在内存中是连续存储的,索引速度非常快
  2. 修改方便

缺点:

  1. 声明时必须指定长度。长度过长内存浪费,长度不够造成溢出错误
  2. 插入数据麻烦

针对于数组的这些缺点,C#中最先提供了ArrayList对象来克服这些缺点

ArrayList

ArrayList继承了IList接口

优点:

  1. 无需指定长度,它的大小是按照其中存储的数据来动态扩充与收缩的
  2. 可以方便地进行数据添加与移除

缺点:

  1. 类型不安全。ArrayList允许插入不同类型的数据,因为ArrayList会把所有插入其中的数据都当作为object类型来处理。
  2. 性能损耗问题。既使我们保证在插入数据的时候都很小心,都插入了同一类型的数据,但在使用的时候,我们也需要将它们转化为对应的原类型来处理。这就存在了装箱与拆箱的操作。

装箱:就是将值类型的数据打包到引用类型的实例中
拆箱:就是从引用数据中提取值类型
装箱与拆箱的过程是很损耗性能的。

泛型List

正是因为ArrayList存在不安全类型与装箱拆箱的缺点,所以在C#2.0后出现了泛型的概念。而List类是ArrayList类的泛型等效类。它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。

So, just use List.

相关文章

  • C# GC与内存管理

    GC即Garbage Collection,垃圾回收的意思。C#的垃圾回收器Garbage Collector会跟...

  • iOS开发基础之内存管理

    为什么要进行内存管理 Objective-C不像JAVA和C#等语言,内存管理依赖垃圾回收(GC)机制;它需要开发...

  • Java GC

    概述 GC => 垃圾回收 = 回收可用空间 + 压缩内存 内存管理 手动内存管理 => C | C++ 自动内存...

  • Swift和 OC的循环引用问题

    在使用面向对象的编程语言进行开发的过程中大都涉及到内存管理相关的问题;JAVA、C#等语言采用GC(垃圾回收)机制...

  • iOS开发中如何解决强引用循环

    在使用面向对象的编程语言进行开发的过程中大都涉及到内存管理相关的问题;JAVA、C#等语言采用GC(垃圾回收)机制...

  • iOS - 老生常谈内存管理(一):引用计数

    简单聊聊 GC 与 RC 随着各个平台的发展,现在被广泛采用的内存管理机制主要有 GC 和 RC 两种。 GC (...

  • 常见GC算法与V8引擎

    内存管理 垃圾回收与常见GC算法 V8引擎的垃圾回收 Performance工具 代码优化实例 内存管理 为什么要...

  • GC

    GC实际是内存的申请与回收的管理控制模块。 GC的背景和一般原理 内存仓库中,仓库与仓库之间循环调用,导致使用数永...

  • Java内存管理机制 ————浅析原理

    java内存管理机制 内存泄漏 内存溢出 内存抖动: 话术整理 首先java的内存管理机制 gc的垃圾回收...

  • JVM 内存结构 和内存回收算法

    一、JVM 内存模型、GC 1.1GC是啥? GC是垃圾回收机制,java中将内存管理交给垃圾回收机制,这是因为在...

网友评论

      本文标题:C# GC与内存管理

      本文链接:https://www.haomeiwen.com/subject/egupuqtx.html