前言

.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 GC 是 Concurrent 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/1和Generation 2后台回收。WorkStation GC和Server 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. 高性能可扩展mysql 笔记(六) SQL执行计划及分页查询优化、分区键统计

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 常见业务处理 一.使用数据库处理常见业务: 案例: 如何对评论进行分页展示 使用 EXPLAIN 获得s ...

  2. Java实现 LeetCode 814 二叉树剪枝 (遍历树)

    814. 二叉树剪枝 给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1. 返回移除了所有不包含 1 的子树的原二叉树. ( 节点 X 的子树为 X 本身,以及所有 X 的后代. ...

  3. Java实现 LeetCode 777 在LR字符串中交换相邻字符(分析题)

    777. 在LR字符串中交换相邻字符 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"L ...

  4. (Java实现) 洛谷 P1091合唱队形

    题目描述 NN位同学站成一排,音乐老师要请其中的(N−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,-,K1,2,-,K,他们的身 ...

  5. Java实现第八届蓝桥杯正则问题

    正则问题 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...

  6. vue+js清除定时器

    注意data数据里面一定要定义Timeout Timeout:Function,//定时器 methods里面 moseovefalse(){//需要执行的方法 var that=this; that ...

  7. 密码学DAY1_02

    目录 1.1 ASCII编码 1.2 凯撒加密 1.2.1 中国古代加密 1.2.2 外国加密 1.2.3 凯撒位移加密--JAVA代码实现 1.2.4 频度分析法破解恺撒加密 1.3现代常用的加密方 ...

  8. python——公司年会抽奖小程序

    张三科技有限公司有300名员工,开年会抽奖,奖项如下一等奖3名 : 泰国五日游二等奖6名 :iphone手机三等奖30名 :避孕套一盒规则:1.一共抽3次,第一次抽3等奖,第二次抽2等奖,第三次压轴抽 ...

  9. 除了FastJson,你也应该了解一下Jackson(一)

    在上月末的时候收到一条关于fastjson安全漏洞的消息,突然想到先前好像已经有好多次这样的事件了(在fastjson上面).关于安全方面,虽然中枪的机率微小,但是在这个信息越来越复杂的时代,安全性也 ...

  10. python—迭代器,生成器与for循环机制

    一:什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代器中的下一项,要么就引起一个stoplteration异常,以终止协议(只能往后走不能往前) 2.可迭代对 ...