C#-垃圾回收机制

什么是GC

垃圾回收器帮助你管理应用程序内存的分配和释放,自动内存管理可避免内存泄漏,或者重复释放内存。

什么时候将发生垃圾回收

1、系统具有较低的物理内存;

2、托管堆上对象占用的内存超过可接收的阈值;

3、调用GC.Collect主动进行垃圾回收。

垃圾回收机制

简单的说,当对象的引用计数为0的时候,CLR会调用GC回收内存;

Generational 分代算法:垃圾回收器会将托管堆分成三代,先遍历第0代中的对象,将没有引用的对象的内存进行回收,未被回收的对象,升级到第1代,此时会如果第0代中内存不够使用或者第1代的内存将满,将会遍历第1代,第0代进行内存回收,同理第1代中未被回收的对象升级成第2代。

非托管资源

GC只能自动管理托管的资源,非托管资源需要开发者自己进行释放,比如文件句柄,数据库连接资源等。

客户端和服务端的GC

CLR对垃圾回收器做了相应的优化,可应对与不同的场景。

工作站 GC

以下是工作站垃圾回收的线程处理和性能注意事项:

  • 回收发生在触发垃圾回收的用户线程上,并保留相同优先级。 因为用户线程通常以普通优先级运行,所以垃圾回收器(在普通优先级线程上运行)必须与其他线程竞争 CPU 时间。 (运行本机代码的线程不会由于服务器或工作站垃圾回收而挂起。)
  • 工作站垃圾回收始终用于只有一个逻辑 CPU 的计算机,无论配置设置如何。

服务器 GC

以下是服务器垃圾回收的线程处理和性能注意事项:

  • 回收发生在多个专用线程上。 在 Windows 上,这些线程以 THREAD_PRIORITY_HIGHEST 优先级运行。
  • 为每个逻辑 CPU 提供一个用于执行垃圾回收的一个堆和专用线程,并将同时回收这些堆。 每个堆都包含一个小对象堆和一个大对象堆,并且所有的堆都可由用户代码访问。 不同堆上的对象可以相互引用。
  • 因为多个垃圾回收线程一起工作,所以对于相同大小的堆,服务器垃圾回收比工作站垃圾回收更快一些。
  • 服务器垃圾回收通常具有更大的段。 但是,这是通常情况:段大小特定于实现且可能更改。 调整应用程序时,不要假设垃圾回收器分配的段大小。
  • 服务器垃圾回收会占用大量资源。 例如,假设在一台有 4 个逻辑 CPU 的计算机上,运行着 12 个使用服务器 GC 的进程。 如果所有进程碰巧同时回收垃圾,它们会相互干扰,因为将在同一个逻辑 CPU 上调度 12 个线程。 如果进程处于活动状态,则最好不要让它们都使用服务器 GC。

参考

工作站和服务器垃圾回收 (GC) | Microsoft Learn

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注