讨论.NET Core 配置对GC 工做模式与内存的影响

引出问题: Asp.net core应用在 Kubernetes上内存使用率太高问题分析

https://mp.weixin.qq.com/s/PqhUzvFpzopU7rVRgdy7eggit

这篇文章中讨论了,在默认状况下,ASP.NET Core程序跑在K8s的Docker中内存使用率>=600MB,致使Docker容器频繁重启。并探讨并作了将ASP.NET Core项目配置System.GC.Server设置为False后,内存小于<=150MB的实验。github

这文主要讲下什么是System.GC.Server,还有GC的二种模式。多线程

对GC工做模式的分类:

.NET Core 两种GC模式:

Server GC / Workstation GC

Server GC :

主要应用于多处理器系统,而且做为ASP.NET Core宿主的默认配置。它会为每一个处理器都建立一个GC Heap,而且会并行执行回收操做。该模式的GC能够最大化吞吐量和较好的收缩性。这种模式的特色是初始分配的内存较大,而且尽量不回收内存,进行回收用时会很耗时,并进行内存碎片整理工做。并发

Workstation GC :

主要应用于单处理器系统,Workstation GC尽量地经过减小垃圾回收过程当中程序的暂停次数来提升性能。低负载且不常在后台(如服务)执行任务的应用程序,能够在禁用并发垃圾回收的状况下使用工做站垃圾回收。特色是会频繁回收,来阻止一次较长时间的回收。asp.net

Concurrent GC 工做方式 :

是一种GC的工做方式,若是你是单处理器的机器,那么即使配置了Concurrent选项为True,也不会生效。Server GC 和Workstation GC均可以开启Concurrent GC,在GC回收的过程当中大部分时间用户线程能够并发运行。但只能影响到2代对象GC的过程,由于0代1代的时间过短了。性能

5.ASP.NET Core Project GC配置:

ASP.NET CORE项目中,经过System.GC.Server配置进行GC模式设置,建立项目默认的GC模式是: System.GC.Server : true (Server GC Concurrent Mode) 每CPU分配GC ;System.GC.Server : false (Workstation GC Concurrent mode),且Concurrent=1。学习

GC 内存分配原则:

GC heap用于保存0、一、2代的对象时,须要向系统申请时的基本单位是Segment,系统会分配指定值大小的Segment用于存储对象,这些值会随着程序的实际执行状况,由GC动态调整。正是因为有Segment的概念因此回出现内存碎片的问题,因此GC在垃圾回收过程当中会进行内存整理,以减小内存碎片提升内存使用率。优化

Segment的大小取决于系统是32位仍是64位,以及它正在运行的垃圾收集器的类型,下表列出了分配时系统所使用的默认值:.net

GC Model 32-bit 64-bit
Workstation GC 16 MB 256 MB
Server GC 64 MB 4 GB
Server GC with > 4 logical CPUs 32 MB 2 GB
Server GC with > 8 logical CPUs 16 MB 1 GB

Segment包括第2代对象,第2代对象会在内存容许的状况尽量多的申请到内存,并使用多个段进行内存存储。
从GC中释放的内存量仅限于Segment的大小,但因为Segment采用动态大小进行了分配,这就使得释放后的大量内存占位致使内存使用率低下,前面也说过了,为了解决这个问题GC要对内存碎片进行整理,并中断全部线程的处理。线程

.NET Core GC的几种配置模式:

Concurrent & Workstation GC

<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>

特色:在吞吐量和相应速度上寻找平衡点, GC Heap数量为1,GC threads在分配空间的线程,GC线程优先权和工做线程具备相同的优先权,工做线程(非GC线程)会由于GC工做过程当中短暂屡次挂起。

Background & Workstation GC

<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>

特色:最大化吞吐量并优化gen2 GC性能, GC Heap数量为1,background GC线程与工做线程有相同优先级,但都低于前台GC线程 ,工做线程(非GC线程)会由于GC工做过程当中短暂屡次挂起,较并发性能更加(针对Gen2的)。

Concurrent & Server GC

<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>

特色:多处理器机器上使用多线程处理相同类型的请求以便最大化服务程序吞吐量, GC Heap数量为每处理器1个,每一个处理器都有一个专职的GC线程,GC线程拥有最高线程的优先级,工做线程(非GC线程)会由于GC工做过程当中会被挂起。

Background & Server GC

<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>

特色:在Concurrent & Server GC基础上优化gen2 GC性能, GC Heap数量为每处理器1个,每一个处理器都有一个专职的GC background线程,background GC线程与工做线程有相同优先级,但都低于前台GC线程,工做线程(非GC线程)会由于GC工做过程当中短暂屡次挂起,较并发性能更加(针对Gen2的)
ephemeral generation的前台GC工做时会挂起其余全部线程。

GC几种模式的分析 (参考资料):

https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

https://github.com/aspnet/Home/issues/2056

推广

GitHub:https://github.com/maxzhang1985/YOYOFx 若是觉还能够请Star下, 欢迎一块儿交流。

.NET Core 开源学习群:214741894

相关文章
相关标签/搜索