前言

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

GC回收过程

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

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

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

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

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

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

回收开始时GC会开始循环遍历Generation 0中的所有对象并标记所有对象是活动对象还是非活动对象,标记完成后会更新活动对象的引用。最后会回收非活动对象占用的内存,并把活动对象压缩后移动到Generation 1中,Generation 1中的或对象在移动到Generation 2是默认不会被压缩的,因为复制大的对象会导致性能的下降。可以通过GCSettings.LargeObjectHeapCompactionMode来配置压缩LOH

GC的回收类型

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

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

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

不同模式下的内存分配

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下回收线程不会超时。

非并行回收:

并行回收

WorkStation GC 后台回收

Server GC 后台回收

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的工作原理,方便在开发中有效区分配使用内存资源,文中如有错误大佬们可以在评论区指出。

.Net Core 中GC的工作原理的更多相关文章

  1. Java中GC的工作原理

    转文: 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能提高整个 ...

  2. 详解Java GC的工作原理+Minor GC、FullGC

    详解Java GC的工作原理+Minor GC.FullGC 引用地址:http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html J ...

  3. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互

    java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...

  4. 【转】优秀的Java程序员必须了解GC的工作原理

    一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率 ,才能提高整个应 ...

  5. 转:ListView中getView的工作原理

    ListView中getView的工作原理: [1]ListView asks adapter “give me a view” (getView) for each item of the list ...

  6. JVM和GC的工作原理

    转载于https://uestc-dpz.github.io JVM Java 虚拟机 Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.JVM ...

  7. 梳理源码中 View 的工作原理

    欢迎Follow我的GitHub, 关注我的掘金. 在View的工作过程中, 执行三大流程完成显示, 测量(measure)流程, 布局(layout)流程, 绘制(draw)流程. 从perform ...

  8. JavaScript中this的工作原理以及注意事项

    在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this  ...

  9. Tomcat中JSP引擎工作原理

    http://blog.csdn.net/linjiaxingqqqq/article/details/7164449 JSP运行环境: 执行JSP代码需要在服务器上安装JSP引擎,比较常见的引擎有W ...

随机推荐

  1. 域对象的作用范围 & 请求的转发和重定向

    1. 和属性相关的方法: ①. 方法 void setAttribute(String name, Object o): 设置属性 Object getAttribute(String name): ...

  2. StringBuffer & StringBuilder

    java.lang.StringBuffer: ①代表可变的字符序列,可以对字符串内容进行增删.                       ②很多方法与String相同,但StingBuffer是可 ...

  3. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)

    上一篇(https://www.cnblogs.com/meowv/p/12971041.html)使用HtmlAgilityPack抓取壁纸数据成功将图片存入数据库,本篇继续来完成一个全网各大平台的 ...

  4. ThreadLocal Thread ThreadLocalMap 之间的关系

    ThreadLocal :每个线程通过此对象都会返回各自的值,互不干扰,这是因为每个线程都存着自己的一份副本.需要注意的是线程结束后,它所保存的所有副本都将进行垃圾回收(除非存在对这些副本的其他引用) ...

  5. vue 使用 elementUI 和 antd 的细微差别

    Checkbox a-checkbox 没有value属性,绑定用checked Collapse 使用折叠面板的时候,antd 的层级关系是 .ant-collapse >.ant-colla ...

  6. Chisel3 - util - MixedVec

    https://mp.weixin.qq.com/s/mO648yx4_ZRedXSWX4Gj2g   可以容纳不同类型的变量的向量.   参考链接: https://github.com/freec ...

  7. Java面向对象 类与对象与方法的储存情况

    栈.堆.方法区 类(含方法)储存在方法区 main函数入栈 堆里面存储方法区中类与方法的地址 main函数调用方法,找堆里面方法的地址,再从方法区找到对应函数,函数入栈,用完出栈 总结: 1.类.方法 ...

  8. Spring ( 三 ) Spring的Bean的装配与生命周期、专用测试

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.对象的生命周期 1.IOC之Bean的生命周期 创建带有生命周期方法的bean public cla ...

  9. Java实现 LeetCode 718 最长重复子数组(动态规划)

    718. 最长重复子数组 给两个整数数组 A 和 B ,返回两个数组中公共的.长度最长的子数组的长度. 示例 1: 输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释 ...

  10. Java实现 LeetCode 572 另一个树的子树(遍历树)

    572. 另一个树的子树 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树 ...