.Net Core 中GC的工做原理

前言

.NET 中GC管理你服务的内存分配和释放,GC是运行公共语言运行时(CLR Common Language Runtime)中,GC能够帮助开发人员有效的分配内存和和释放内存,大多数状况下是不须要去担忧的,可是有时候服务老是是出现莫名的问题,因此仍是有必要了解一下GC的基础知识的。这里就不介绍内存方面的知识了。html

GC回收过程

GC将对象分为大对象和小对象,若是对象的大小大于或者等于85000byte将被视为大对象,大对象会被分配到到(LOH) Large Object Heap中去。json

GC有一个代数的概念Generation,分为三代服务器

20200623172623

  • Generation 0: 0代,这里面都是生命周期很短的对象,好比临时变量,当你new一个对象的时候该对象都会在Generation 0中,这里的对象将很快的被GC回收,可是当你new的是一个大对象的时候它会直接进去大对象堆(LOH)并发

  • Generation 1: 1代,这一代包含的也基本是生命周期很短的对象。它是短时间对象和长期对象之间的缓冲区。性能

  • Generation 2: 2代,这一代包含的都是生命周期长的对象,它们都是从1代和2代中选拔出来的,LOH属于2代。线程

当分配的对象使用的内存超出了GC的阈值时回收就会开始。阈值是随着服务的运行GC本身调整的。或者直接调用GC.Collect方法也能够开始回收。3d

回收开始时GC会开始循环遍历Generation 0中的全部对象并标记全部对象是活动对象仍是非活动对象,标记完成后会更新活动对象的引用。最后会回收非活动对象占用的内存,并把活动对象压缩后移动到Generation 1中,Generation 1中的或对象在移动到Generation 2是默认不会被压缩的,由于复制大的对象会致使性能的降低。能够经过GCSettings.LargeObjectHeapCompactionMode来配置压缩LOHcode

GC的回收类型

GC 回收有两种类型,WorkStation GC(工做站)和Server GC(服务器),.Net Core服务默认状况下时使用WorkStation GC工做站模式来回收。htm

  • Server GC会拥有更大的内存,Server GC会为每一个处理器建立一个用于执行垃圾回收的堆和专用线程,每一个堆都拥有一个小对象堆和大对象堆,而且全部的堆均可以访问。 不一样堆上的对象能够相互引用。由于多个垃圾回收线程一块儿工做,因此对于相同大小的堆Server GC垃圾回收比WorkStation GC垃圾回收更快一些。可是Server GC回收会占用大量资源,这种模式的特色是初始分配的内存较大,而且尽量不回收内存,进行回收用时会很耗时,并进行内存碎片整理工做。对象

  • Workstation GC的内存相对于Server GC就很小啦,且它的回收线程就是服务的线程且有较高的优先级,由于必须与其余线程竞争 CPU 时间来进行回收。

不一样模式下的内存分配
20200623154852

GC的回收模式

GC有三种回收模式

  • Non-Concurrent GC 非并行回收模式:在非并行模式下,回收时候会挂起全部其余的线程影响服务的性能。

  • Concurrent GC 并行回收模式: 并行会后能够解决非并行回收引发的线程挂起,让其余线程和回收线程一块儿运行,使服务能够更快的响应,并行回收只会发生在Generation 2中,Generation 0/1始终都是非并发的,由于他们都是小对象回收的速度很快。在并行回收的时候咱们依旧能够分配对象到Generation 0/1中。

  • Background GC 后台回收模式:Background GCConcurrent GC的加强版本。 区别在Background GC回收Generation 2的时容许了Generation 0/1 进行清理。在WorkStation GC下会使用一个专用的后台垃圾回收线程,而Server GC下会使用多个线程来进行回收。且Server GC下回收线程不会超时。

非并行回收:
20200623143747

并行回收
20200623170251

WorkStation GC 后台回收
20200623145944

Server GC 后台回收
20200623150013

GC回收类型配置

推荐使用runtimeconfig.json文件和环境变量COMPlus_gcServer来配置。

COMPlus_gcServer 0 = WorkStation GC
COMPlus_gcServer 1 = Server GC

{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.Server": true 
         //true - Server GC  false - WorkStation GC
      }
   }
}

GC回收模式配置

推荐使用runtimeconfig.json文件和环境变量COMPlus_gcConcurrent来配置。

COMPlus_gcConcurrent 0 =Non-Concurrent GC
COMPlus_gcConcurrent 1 =Background GC

{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.Concurrent": true 
         //true- Background GC false -Non-Concurrent GC
      }
   }
}

强制回收

在一些特殊的状况下强制回收是能够提升服务的性能的,能够向GC.Collect()提供GCCollectionMode枚举值触发强制回收。

  • Default :默认的回收设置。
  • Forced :当即强制进行垃圾回收。
  • Optimized : GC来判断时间是不是回收对象的最佳时间,如GC断定回收效率不高所以回收不合理的状况下将返回不回收对象。
GC.Collect( (int) GCCollectionMode.Forced);

延迟回收

在咱们的服务在检索数据或者处理逻辑的时候可能会发生垃圾回收,从而妨碍性能,能够经过System.Runtime.GCLatencyMode来配置延迟回收

  • GCLatencyMode.LowLatency:禁止Generation 2回收,只回收Generation 0/1,这个只能在短期内使用,若是长时间使用内存处于压力下GC仍是会触发回收,这个配置只对WorkStation GC可用。

  • GCLatencyMode.SustainedLowLatency :禁止Generation 2 Foreground GC (前台回收),只回收Generation 0/1Generation 2后台回收。WorkStation GCServer GC均可以使用,且能够长时间使用,可是若是禁用Background GC,将没法使用。

GC.Collect( (int) GCLatencyMode.SustainedLowLatency);

参考文章

从ASP.NET Core 3.0 preview 特性,了解CLR的Garbage Collection

微软文档

总结

参考了一些大佬和官方的文档简单的去了解了一下GC的工做原理,方便在开发中有效区分配使用内存资源,文中若有错误大佬们能够在评论区指出。

相关文章
相关标签/搜索