在C#(C Sharp)编程语言中,GC是指垃圾回收(Garbage Collection)的缩写。
垃圾回收是一种自动内存管理机制,在程序运行时负责自动分配和释放对象所占用的内存空间。它减轻了开发人员手动管理内存的负担,并帮助防止内存泄漏和悬挂指针等常见问题。
C#中的垃圾回收器负责跟踪对象的引用以及它们在内存中的分配和使用情况。当一个对象不再被引用时(也就是没有其他对象指向它),垃圾回收器会将其标记为垃圾,并将其所占用的内存空间释放出来,以供后续的对象使用。
这个过程是自动进行的,开发人员无需手动释放对象,从而提高了开发效率和程序的可靠性。
工作原理
在C#中,当一个对象不再被引用时,指的是没有任何变量或对象引用指向该对象。换句话说,没有方式可以通过现有的代码访问或使用该对象。
当一个对象被创建并分配内存时,可以使用变量或其他对象引用来跟踪和操作该对象。如果所有的引用都被设置为null
或超出了其作用域(例如,在方法结束后),那么该对象将不再被引用。这意味着没有任何方式可以从应用程序的其他部分访问该对象,它变得无法触及。
一旦没有引用指向一个对象,垃圾回收器会将其标记为垃圾,并在合适的时机自动进行垃圾回收。
垃圾回收器会检查和回收不再被引用的对象所占用的内存空间,以便后续的对象可以使用。这个过程是自动的,开发人员无需手动介入。
需要注意的是,只要有一个引用指向某个对象,它就会被视为"活动"对象,并且不会被垃圾回收器回收。
因此,即使一个对象在某一时刻不再被其他对象引用,只要仍然存在对该对象的引用,它就不会被垃圾回收器回收。
垃圾回收器的工作原理通常基于以下两个主要的策略:
-
标记-清除(Mark and Sweep):该策略通过追踪对象之间的引用关系,标记出所有可达的对象。然后,清除未被标记的对象,并将内存空间进行整理,以便后续的对象分配。
-
分代回收(Generational Collection):该策略将堆内存分为不同的代,通常是新生代、中间代和老年代。新创建的对象首先被分配到新生代,而且大部分对象在创建后很快就变得不可达。因此,垃圾回收器会更频繁地对新生代进行垃圾回收,以提高效率。当对象存活足够长时间时,它们会被晋升到下一个代,并且在老年代中进行更少的垃圾回收操作。
具体过程演示:假设有a,b,c,d对象,都是引用类型。
声明一个a对象,就会在0代(也就是新生代)里面分配一个内存空间,接着是b,c,d对象的分配,检查0代里是否有分配的内存空间,有就继续分配。
假设到d的时候,0代内存已经满了,这个时候就会触发垃圾回收,它会从根部开始找0代里面有哪些房间是没有被外面变量所引用的,因为a,b,c变量都有引用(即a,b,c变量都与对应的房间有“连接”/“羁绊”),所以a,b,c房间都属于可达的对象,而剩下的没有“连接”/“羁绊”的内存就会释放。
接着搬迁可达对象,就是把0代里这些有“羁绊”的对象搬迁到第1代内存中。
修改引用地址,a,b,c三个房间搬迁过来后可能是不连续的,所以把它们按abc顺序再整齐的排放好,所以(引用地址)门牌号会变。
1代也会有满的时候,那么就会触发1代的垃圾回收,0代和1代一起释放。
释放过后,会把有引用的abc再搬迁到2代内存。
(注意:每一代满的时候才会触发垃圾回收,而且会连上一代的也触发。也就是说1代会和0代一起触发。如果2代也满了,那就0,1,2代一起释放。所以我们会发现有引用的对象基本就会存放在2代内存里面。)