CLR的GC工作模式介绍(Workstation和Server)
CLR的核心功能之一就是垃圾回收(garbage collection),关于GC的基本概念本文不在赘述。这里主要针对GC的两种工作模式展开讨论和研究。
Workstaction模式介绍
该模式设计的目的是用于客户端类的应用(Client),这类应用的部署特点是同一台机器会部署很多应用程序,并且这些应用程序的性能要求并没有服务器程序(nginx、asp.net等)那么高。那么在此种场景下,GC做了哪些设计和调整呢?
- 首先,最显著的特点是当触发垃圾回收时,CLR并没有安排专用的线程来执行垃圾回收操作,仅仅是使用当前触发GC的线程去执行后续操作,并且连线程优先级都没有提升。那么自然GC操作就要和其它用户线程来平等竞争CPU使用。
- 其次,GC堆的数量上也仅仅只有1组(1个大对象堆、1个小对象堆),这样可以更少的占用内存空间。
Server模式介绍
顾名思义,Server模式就是针对服务器场景设计的,此类应用的部署特点是服务器内存大CPU核心多,部署的程序数量少(基本都是专机专用),但是对程序性能要求非常高。于是这种模式下,GC的也做了相应的调整:
- 基于CPU核心多的特点,CLR则分配专用的线程(按照CPU核心数分配)来执行GC操作,且专用线程的优先级为THREAD_PRIORITY_HIGHEST,也比普通托管线程更高。这样当需要执行GC时可以保证优先占用CPU,从而尽快完成GC操作,尽快满足内存申请所需空间。
- 基于内存大的特点,那就多分配GC堆,且每个堆更大,从而避免频繁的触发GC。具体来说,GC堆数量是根据CPU核心数来分配,比如8核CPU就分配8组GC堆。至于堆的默认大小,将按照如下规则分配:
注意上表的值是每个堆的大小,对多核CPU来说,Server模式的GC堆分配空间显然是大于Wordstation模式的。
什么是后台垃圾回收(Background)?
我们知道CLR根据GC次数把对象分为0代、1代、2代。其中01代执行的频率高、耗时短,也被称为ephemeral generations。 根据CLR的设计,执行01代垃圾回收时,所有托管线程是被短暂挂起,直到垃圾回收结束后再恢复执行。但是执行2代的垃圾回收会耗时相对更长,如果也挂起全部线程,无疑会对程序响应造成较大的影响。
因此CLR提出单独分配专用线程,用来执行2代垃圾回收,且此线程执行时不会挂起其它线程,从而降低对程序的影响。注意此处2代垃圾回收其实是包含了之前的01代的,只不过01代执行很短暂且01代执行时会依旧会挂起全部线程。
关于Background专用线程的数量,workstation模式拥有1个专用线程,server模式分配和逻辑处理器数量一致的专用线程。
在workstation模式下background回收的执行示意图:
上图的解读:
- GC THREAD就是background专用线程,可以看到其执行期间,其它线程没有影响。
- 其中绿色箭头代表01代的回收操作,可以看到其执行就是在普通的THREAD1线程,而且挂起了其它所有线程。
在server模式下background回收的执行示意图:
上图解读:
- GC THREAD1/2代表01代的专用线程,BGC THREAD1/2代表background专用线程。
- 同样的background线程执行回收时,其它线程不受影响。
- 绿色箭头代表01代的回收操作,可以看到挂起了其它所有线程。
需要额外说明是,background是最新的叫法,之前版本称为concurrent。他们之间的升级关系如下:
workstation模式 | server模式 | |
.NET Framework 4之前 | concurrent gc | 不支持 |
.NET Framework 4 | background gc | 不支持 |
.NET Framework 4.5及之后 | background gc | background gc |
二个模式的对比
workstation模式 | server模式 | 说明 | |
专用线程 | 无 | 有单独的专用线程,且数量等于CPU核心数 | server模式充分利用多核特性,最大化保证快速完成GC操作。 |
gc执行的优先级 | 普通 | THREAD_PRIORITY_HIGHEST | workstation模式线程执行GC操作需要和普通业务线程平等竞争CPU,GC不能最快的完成。 |
gc堆数量 | 1 | 多个,数量等于CPU核心数 |
workstation模式堆数量少且内存更少,但是容易引起GC。 server模式堆数量多占用内存更多,可以降低触发GC的次数,进而提高程序的响应性能。 |
background支持情况 | 支持,但只会分配1个background专用线程 | 支持,分配的background专用线程数量等于CPU核心数 |
怎么设置不同工作模式?
项目文件csproj中设置:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
</PropertyGroup>
</Project>
runtimeconfig.json 文件设置:
{
"runtimeOptions":{
"configProperties":{
"System.GC.Server":true,
"System.GC.Concurrent":true
}
}
}
单独说明一点,对于单核CPU的计算机,无论如何配置都是workstation模式,当然现代计算机这种情况极少了。
通过dump验证上述机制
对于workstation模式的程序进程,通过dump查看gc堆信息和gc模式信息分别如下:
0:004> !eeversion
6.0.21.52210 free
Workstation mode
SOS Version: 6.0.5.7301 retail build
0:004> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x0000024E80001030
generation 1 starts at 0x0000024E80001018
generation 2 starts at 0x0000024E80001000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
0000024E80000000 0000024E80001000 0000024E8010DFE8 0000024E80112000 0x10cfe8(1101800) 0x111000(1118208)
Large object heap starts at 0x0000024E90001000
segment begin allocated committed allocated size committed size
0000024E90000000 0000024E90001000 0000024E9004FD40 0000024E90050000 0x4ed40(322880) 0x4f000(323584)
Pinned object heap starts at 0x0000024E98001000
0000024E98000000 0000024E98001000 0000024E98006C50 0000024E98012000 0x5c50(23632) 0x11000(69632)
Total Allocated Size: Size: 0x161978 (1448312) bytes.
Total Committed Size: Size: 0x160000 (1441792) bytes.
------------------------------
GC Allocated Heap Size: Size: 0x161978 (1448312) bytes.
GC Committed Heap Size: Size: 0x160000 (1441792) bytes.
对于server模式的程序进程,通过dump查看gc堆信息和gc模式信息分别如下:
查看代码
0:012> !eeversion
6.0.21.52210 free
Server mode with 8 gc heaps
SOS Version: 6.0.5.7301 retail build
0:015> !eeheap -gc
Number of GC Heaps: 8
------------------------------
Heap 0 (000001E88D3F3AD0)
generation 0 starts at 0x000001E88EF51030
generation 1 starts at 0x000001E88EF51018
generation 2 starts at 0x000001E88EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001E88EF50000 000001E88EF51000 000001E88EF51048 000001E88EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001EC8EF51000
segment begin allocated committed allocated size committed size
000001EC8EF50000 000001EC8EF51000 000001EC8EF51018 000001EC8EF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED0EF51000
000001ED0EF50000 000001ED0EF51000 000001ED0EF53010 000001ED0EF62000 0x2010(8208) 0x11000(69632)
Allocated Heap Size: Size: 0x2070 (8304) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 1 (000001E88D41F830)
generation 0 starts at 0x000001E90EF51030
generation 1 starts at 0x000001E90EF51018
generation 2 starts at 0x000001E90EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001E90EF50000 000001E90EF51000 000001E90EF51048 000001E90EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001EC9EF51000
segment begin allocated committed allocated size committed size
000001EC9EF50000 000001EC9EF51000 000001EC9EF51018 000001EC9EF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED1EF51000
000001ED1EF50000 000001ED1EF51000 000001ED1EF51018 000001ED1EF52000 0x18(24) 0x1000(4096)
Allocated Heap Size: Size: 0x78 (120) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 2 (000001E88D426EE0)
generation 0 starts at 0x000001E98EF51030
generation 1 starts at 0x000001E98EF51018
generation 2 starts at 0x000001E98EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001E98EF50000 000001E98EF51000 000001E98EF51048 000001E98EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001ECAEF51000
segment begin allocated committed allocated size committed size
000001ECAEF50000 000001ECAEF51000 000001ECAEF51018 000001ECAEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED2EF51000
000001ED2EF50000 000001ED2EF51000 000001ED2EF51430 000001ED2EF52000 0x430(1072) 0x1000(4096)
Allocated Heap Size: Size: 0x490 (1168) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 3 (000001ED9B54AFB0)
generation 0 starts at 0x000001EA0EF51030
generation 1 starts at 0x000001EA0EF51018
generation 2 starts at 0x000001EA0EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001EA0EF50000 000001EA0EF51000 000001EA0EF51048 000001EA0EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001ECBEF51000
segment begin allocated committed allocated size committed size
000001ECBEF50000 000001ECBEF51000 000001ECBEF51018 000001ECBEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED3EF51000
000001ED3EF50000 000001ED3EF51000 000001ED3EF51018 000001ED3EF52000 0x18(24) 0x1000(4096)
Allocated Heap Size: Size: 0x78 (120) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 4 (000001ED9B576570)
generation 0 starts at 0x000001EA8EF51030
generation 1 starts at 0x000001EA8EF51018
generation 2 starts at 0x000001EA8EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001EA8EF50000 000001EA8EF51000 000001EA8EF51048 000001EA8EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001ECCEF51000
segment begin allocated committed allocated size committed size
000001ECCEF50000 000001ECCEF51000 000001ECCEF51018 000001ECCEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED4EF51000
000001ED4EF50000 000001ED4EF51000 000001ED4EF51018 000001ED4EF52000 0x18(24) 0x1000(4096)
Allocated Heap Size: Size: 0x78 (120) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 5 (000001ED9B5A2420)
generation 0 starts at 0x000001EB0EF51030
generation 1 starts at 0x000001EB0EF51018
generation 2 starts at 0x000001EB0EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001EB0EF50000 000001EB0EF51000 000001EB0EF673D8 000001EB0EF72000 0x163d8(91096) 0x21000(135168)
Large object heap starts at 0x000001ECDEF51000
segment begin allocated committed allocated size committed size
000001ECDEF50000 000001ECDEF51000 000001ECDEF51018 000001ECDEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED5EF51000
000001ED5EF50000 000001ED5EF51000 000001ED5EF53010 000001ED5EF62000 0x2010(8208) 0x11000(69632)
Allocated Heap Size: Size: 0x18400 (99328) bytes.
Committed Heap Size: Size: 0x22000 (139264) bytes.
------------------------------
Heap 6 (000001ED9B5CE2D0)
generation 0 starts at 0x000001EB8EF51030
generation 1 starts at 0x000001EB8EF51018
generation 2 starts at 0x000001EB8EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001EB8EF50000 000001EB8EF51000 000001EB8EF51048 000001EB8EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001ECEEF51000
segment begin allocated committed allocated size committed size
000001ECEEF50000 000001ECEEF51000 000001ECEEF51018 000001ECEEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED6EF51000
000001ED6EF50000 000001ED6EF51000 000001ED6EF51018 000001ED6EF52000 0x18(24) 0x1000(4096)
Allocated Heap Size: Size: 0x78 (120) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
Heap 7 (000001ED9B5FA180)
generation 0 starts at 0x000001EC0EF51030
generation 1 starts at 0x000001EC0EF51018
generation 2 starts at 0x000001EC0EF51000
ephemeral segment allocation context: none
segment begin allocated committed allocated size committed size
000001EC0EF50000 000001EC0EF51000 000001EC0EF51048 000001EC0EF52000 0x48(72) 0x1000(4096)
Large object heap starts at 0x000001ECFEF51000
segment begin allocated committed allocated size committed size
000001ECFEF50000 000001ECFEF51000 000001ECFEF51018 000001ECFEF52000 0x18(24) 0x1000(4096)
Pinned object heap starts at 0x000001ED7EF51000
000001ED7EF50000 000001ED7EF51000 000001ED7EF51018 000001ED7EF52000 0x18(24) 0x1000(4096)
Allocated Heap Size: Size: 0x78 (120) bytes.
Committed Heap Size: Size: 0x2000 (8192) bytes.
------------------------------
GC Allocated Heap Size: Size: 0x1ab58 (109400) bytes.
GC Committed Heap Size: Size: 0x30000 (196608) bytes.
总结
本文主要参阅了微软官方文档,对GC的工作模式进行了探究和验证。可以看到,微软设计这2个GC工作模式的目的是为了.net应用程序在不同场景下有好的程序表现,并没有孰优孰劣的问题。这个功能特点可以类比现在自动挡汽车的工作模式有节能模式、道路模式、雪地模式、沙漠模式一样。因此,在实际开发程序时,对普通客户端应用如winfrom一般选择workstation模式,对于服务器程序如asp.net 一般选择server模式。
参考资料
- 垃圾回收的基本知识 | Microsoft Docs
- Workstation vs. server garbage collection (GC) | Microsoft Docs
- 后台垃圾回收 | Microsoft Docs
- 垃圾回收器配置设置 - .NET | Microsoft Docs
CLR的GC工作模式介绍(Workstation和Server)的更多相关文章
- 讨论.NET Core 配置对GC 工作模式与内存的影响
引出问题: Asp.net core应用在 Kubernetes上内存使用率过高问题分析 https://mp.weixin.qq.com/s/PqhUzvFpzopU7rVRgdy7eg 这篇文章中 ...
- .NET Core 配置GC工作模式与内存的影响
.NET Core 配置GC工作模式与内存的影响 .NET Core GC 原文:https://blog.markvincze.com/troubleshooting-high-memory-usa ...
- rsync的介绍及参数详解,配置步骤,工作模式介绍
rsync的介绍及参数详解,配置步骤,工作模式介绍 rsync是类unix系统下的数据镜像备份工具.它是快速增量备份.全量备份工具. Sync可以远程同步,支持本地复制,或者与其他SSH.rsync主 ...
- 【RabbitMQ】工作模式介绍
一.前言 之前,笔者写过< CentOS 7.2 安装 RabbitMQ> 这篇文章,今天整理一下 RabbitMQ 相关的笔记便于以后复习. 二.模式介绍 在 RabbitMQ 官网上提 ...
- LVS的工作模式介绍和NAT模式&DR模式实验步骤
一:LVS介绍 二.LVS的NAT和DR模式的实验及配置步骤 一.LVS的简单介绍 linux virtual server 简单来讲lvs是一段内核代码 类似于netfilter本身是一框架但不提供 ...
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_10.RabbitMQ研究-工作模式-路由工作模式介绍
队列在绑定交换机的时候可以指定routingKey, 路由模式: 1.每个消费者监听自己的队列,并且设置routingkey. 2.生产者将消息发给交换机,由交换机根据routingkey来转发消息到 ...
- .NET 中 GC 的模式与风格
垃圾回收(GC)是托管语言必备的技术之一.GC 的性能是影响托管语言性能的关键.我们的 .NET 既能写桌面程序 (WINFROM , WPF) 又能写 web 程序 (ASP.NET CORE),甚 ...
- LVS工作模式与调度算法
LVS三种工作模式.十种调度算法介绍 工作模式介绍: 1.Virtual server via NAT(VS-NAT) 优点:集群中的物理服务器可以使用任何支持TCP/IP操作系统,物理服务器可以分配 ...
- 【嵌入式开发】ARM 芯片简介 (ARM芯片类型 | ARM处理器工作模式 | ARM 寄存器 | ARM 寻址)
: 12MHz 晶振 对应 405 ~ 532 MHz 处理速度; -- : 16K 指令缓存, 16K 数据缓存; -- : 32KB 指令缓存, 32KB 数据缓存; (3) 内存接口对比 : 提 ...
随机推荐
- SpringCloud整合Hystrix
1.Hystrix简介 Hystrix是由Nefflix开源的一个延迟和容错库,用于隔离访问远程系统.服务或第三方库,防止级联失败,从而提升系统的可用性.容错性与局部应用的弹性,是一个实现了超时机制和 ...
- 谷歌CEO桑达尔·皮查伊:区块链可能撼动云计算
谷歌CEO桑达尔·皮查伊在周二的季度收益电话会议上承认了Web3和区块链的力量. 皮查伊表示,Web3描述了基于区块链的互联网新愿景,区块链是一种分散.安全.透明的技术,支持加密货币网络.不可替代代币 ...
- X000001
一些相互无关联的题目的集合 都是码量不大,略有思维难度的题 做起来还是很舒适的 P6312 [PA2018]Palindrom 空间限制很小,不足以存下整个字符串,故暴力判断不可行. 考虑使用字符串哈 ...
- JS 选择结构语句与循环结构语句
笔记整理自:廖雪峰老师的JS教程 选择结构 与Java使用一致. 需要注意的 JavaScript把null.undefined.0.NaN和空字符串''视为false,其他值一概视为true. 循环 ...
- 区段统计 mysql 语句 case when then end as
EXPLAIN SELECT COUNT(*),CASEWHEN device_width > 729 THEN '>729'WHEN device_width BETWEEN '720' ...
- jdk1.5新特性之-----自动装箱与自动拆箱
import java.util.ArrayList; /* jdk1.5新特性之-----自动装箱与自动拆箱. java是面向对象 的语言,任何事物都可以使用类进行描述,sun就使用了 一些类描述j ...
- Keepalived配置与使用(1)
介绍 Keepalived是一个基于VRRP协议来实现的WEB服务高可用方案,可以利用其来避免单点故障.一个WEB服务至少会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为 ...
- 从服务间的一次调用分析整个springcloud的调用过程(一)
首先我们知道springcloud是一个微服务框架,按照官方文档的说法,springcloud提供了一些开箱即用的功能: 1 分布式/版本化配置 2 服务的注册与发现 3 路由 4 服务到服务之间调用 ...
- Solution -「WF2011」「BZOJ #3963」MachineWorks
\(\mathcal{Description}\) Link. 给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i ...
- Solution -「UNR #5」「UOJ #671」诡异操作
\(\mathcal{Desciprtion}\) Link. 给定序列 \(\{a_n\}\),支持 \(q\) 次操作: 给定 \(l,r,v\),\(\forall i\in[l,r], ...