menu 极光萝卜
记:.Net Core应用GC(垃圾回收)模式配置
folder_special 笔记    access_time 2018-5-4   remove_red_eye 1225   comment 2

近期在云服务器上运行了两个.Net Core应用,经过一段时间的观察后发现自从上了这两个应用后服务器的内存使用率一直上升并且居高不下,我意识到问题出现在了我这两个.Net Core程序上面,检查了一遍代码后没有发现什么奇怪的地方,所以把问题定位在.Net Core的GC上面,通过百度和谷歌对.Net Core的GC进行相关检索后发现了问题所在——GC工作模式的配置。

通过相关资料了解以下信息:

  • .Net Core默认的GC工作模式为Server GC模式
  • 生产环境下可通过配置.runtimeconfig.json文件来调整GC工作模式

GC工作模式:

Server GC:

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

Workstation GC:

主要应用于单处理器系统,Workstation GC尽可能地通过减少垃圾回收过程中程序的暂停次数来提高性能。低负载且不常在后台(如服务)执行任务的应用程序,可以在禁用并发垃圾回收的情况下使用工作站垃圾回收。特点是会频繁回收,来阻止一次较长时间的回收。

Concurrent GC 工作方式:

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


通过了解后可以确定居高不下的内存使用率就出在这个默认的Server GC模式上了,找到了问题那么就开始解决问题,立马修改我的两个.Net Core应用的.runtimeconfig.json文件,在经过考虑后选择Workstation GC&Concurrent GC开启的配置,如下:

{
  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": false,
	  "System.GC.Concurrent":true
    }
  }
}

那么效果如何呢?我是在昨天晚上(05/03)调整了GC工作模式并重启了两个应用,来看看实际数据:

TIM截图20180504201304.png

这是从阿里云上的服务器数据监控图表截下来的图,可以看到在前段时间~04-23期间,我的服务器内存使用几乎一直居高不下。

在04-23下午我有一次升级配置的操作,这时候重启了服务器。但内存总量增加后内存使用率并没有降低,从04-23~05-03这期间的图可以看出,已用内存(图中绿线,actualused+buffers+cached)从一开始就超过90%,并且实际使用内存(图中黄线,actualused)在期间持续上升并最终超过90%。

最终,在05-03晚上,我调整了两个应用的GC配置并重启两个应用后,到现在,虽然只有差不多一天的时间,但通过图可以明显的看出效果,实际使用内存有非常明显的降低并且没有太大的上升趋势,已用内存也不想之前一样在90%居高不下,有了明显的下降。


从两个应用目前的体验上来看,与Server GC模式在体验上并没有发现太大区别,但内存占用大大降低。对我目前的服务器来说,本身属于低配置,并且服务器上不仅仅只运行这两个.Net Core应用,选择Workstation GC模式比较适合,毕竟如果出现其他应用需要内存的时候,Server GC模式下几乎没有内存来进行分配了,这时候可能会全部崩盘,比如这个网站跟着一起挂(╬゚д゚)

local_offer .netcore 阿里云
赞助商链接:

发表评论:

account_circle
昵称不能为空
email
邮箱格式错误
link
网站格式错误
textsms

2条评论:

Run
2018-07-09 16:09
配置文件是怎么写的?
2018-07-09 19:01
@Run:一般.Net Core应用发布后目标文件夹会有一个以应用的名字为名的.runtimeconfig.json文件(例如:application.runtimeconfig.json),直接编辑文件,类似文章中贴出的Json代码那样修改就能达到效果了