C# 垃圾回收机制(GC) 的概述 资源清理 内存管理

简介: C# 垃圾回收机制(GC) 的概述 资源清理 内存管理

什么是垃圾回收

在编写程序时,会产生很多的数据 比如:int string 变量,这些数据都存储在内存里,如果不合理的管理他们,就会内存溢出导致程序崩溃

C#内置了自动垃圾回收GC,在编写代码时可以不需要担心内存溢出的问题 变量失去引用后 GC会帮我们自动回收,但不包括数据流,和一些数据库的连接,这就需要我们手动的释放资源

总结:让内存利用率更高


什么样子的对象才会给回收?

GC只会回收 的内存 ,而 值类型在 中的使用完后马上就会给释放,并不需要 GC 进行处理,堆中的没有被引用或者null的对象才会被回收,静态的变量也不会被回收

上面说到他并不会回收一些数据流

比如: Stream StreamReader StreamWrite HttpWebResponse 网络端口 等还有一些数据库的连接

这些对象需要调用 Close() 或者 Dispose() 方法进行 手动回收

总结:没有被引用的对象 或为 null的


什么时候进行垃圾回收?

什么时候回收这些都由操作系统决定,一般不需要进行理会全由系统调用,如有特殊情况,明确的需要进行释放 也可以强制的垃圾回收

GC.Collect()

正常情况下 非常不建议使用这方法,这会让程序暂停但时间很短,会影响执行效率

需要注意的是 给释放后的内存是无法在找回的

总结:由操作系统决定 但也可以强制释放 正常情况不需要理会内存问题


效率问题(重要)

除非马上需要进行非常消耗内存的操作 其他情况尽量不要调用GC.Collect();

测试:

for (int i = 0; i < 90000; i++)           
string str = i.ToString();
//假装我是一个方法哈

测试时间:20毫秒

假如每次使用完方法后强制垃圾回收

for (int i = 0; i < 90000; i++)
            {
string str = i.ToString();
 //假装我是一个方法哈
  GC.Collect();          
            }

测试时间:4793毫秒

性能相差200倍


“代”的机制

使用代的机制进行垃圾回收 可以大大的提示垃圾回收的性能

垃圾回收共分3代

索引 【0】【1】 【2】共3个

每次创建对象的时候 都是在第0代 分配内存 并且每一代都配有初始内存空间



假设现在程序已经跑了一段时间了 而第0代分配的2MB的空间已满了



这时候就会进行 垃圾回收 把失去引用的对象释放 此时未使用完的对象将进入到第1代



垃圾回收后 第0代就已经空了 后面创建的对象就会重新放入第0代


以此类推 0代满后 又会重新垃圾回收 还在使用的对象又会放入第1代

此后运行一段时间 1代也已经满了 而0代还在使用的对象也会移动到1代 这时候已经不够放了 又会进行垃圾回收 1代的将移动到2代 0代的将移动到1代



以此类推

假如我代数都满了 但对象我都还在使用 并没有回收多少 这时GC就会自动的把初始内存给扩大 比如原来2MB 扩大到4MB 还不够使用的情况下就会抛出异常

int n  =GC.MaxGeneration;
//获取系统支持最大的代数

结果:2

GC.Collect(1); 
   //指定回收第2代内存   注意从0开始

析构函数

该函数是在类使用完成后调用的,一些非托管资源 Sream 可以在此处调用Dispose()方法进行释放内存,一个类只有一个析构函数而且无法继承他

~Class1()
        {
            Console.WriteLine("我给调用了");
        }

但有时候该函数并不会调用,无法控制何时调用析构函数,因为这是由垃圾回收器决定的,在垃圾回收时先运行析构函数在回收其他对象。

public void A()
        {
            Console.WriteLine("xxxx");
        }
        ~Class1()
        {
            Console.WriteLine("我给调用了");
        }

可以看到 析构函数 并没有给使用,假如你写的是一些释放资源的方法,那也不会执行该函数


相关文章
|
1月前
|
JavaScript 前端开发 Java
垃圾回收机制会导致内存泄漏吗?
【10月更文挑战第29天】虽然JavaScript的垃圾回收机制本身是为了有效地管理内存,但开发者在编写代码时需要注意上述这些可能导致内存泄漏的情况,遵循良好的编程习惯,及时释放不再使用的资源,以确保程序能够高效地利用内存资源,避免出现内存泄漏问题。
|
20天前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
31 3
|
26天前
|
算法 Java 开发者
Java内存管理与垃圾回收机制深度剖析####
本文深入探讨了Java虚拟机(JVM)的内存管理机制,特别是其垃圾回收机制的工作原理、算法及实践优化策略。不同于传统的摘要概述,本文将以一个虚拟的“城市环卫系统”为比喻,生动形象地揭示Java内存管理的奥秘,旨在帮助开发者更好地理解并调优Java应用的性能。 ####
|
1月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
49 6
|
18天前
|
存储 监控 算法
Java内存管理的艺术:深入理解垃圾回收机制####
本文将引领读者探索Java虚拟机(JVM)中垃圾回收的奥秘,解析其背后的算法原理,通过实例揭示调优策略,旨在提升Java开发者对内存管理能力的认知,优化应用程序性能。 ####
32 0
|
2月前
|
存储 监控 算法
Java中的内存管理与垃圾回收机制解析
本文深入探讨了Java编程语言中的内存管理方式,特别是垃圾回收机制。我们将了解Java的自动内存管理是如何工作的,它如何帮助开发者避免常见的内存泄漏问题。通过分析不同垃圾回收算法(如标记-清除、复制和标记-整理)以及JVM如何选择合适的垃圾回收策略,本文旨在帮助Java开发者更好地理解和优化应用程序的性能。
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
36 3
|
3天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
31 12
|
1月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
51 4
|
3月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
51 2