找回密码
 立即注册
首页 业界区 安全 工作站模式和服务器模式 以及并发GC

工作站模式和服务器模式 以及并发GC

拙因 2025-6-1 18:16:02
1.背景:

 .NET Framework 的 CLR(公共语言运行时,Common Language Runtime)的两种不同构建版本:Workstation(工作站版本) 和 Server(服务器版本)。这两个版本在底层实现上存在差异,主要针对不同的应用场景进行优化。
在早期 .NET Framework(如 2.0-3.5)中,CLR 的宿主(Hosting)机制通过不同的非托管代码模块实现,具体表现为:

  • mscorwks.dll(Microsoft Common Object Runtime WorkStation):工作站版本的 CLR 核心模块。
  • mscorsvr.dll(Microsoft Common Object Runtime Server):服务器版本的 CLR 核心模块。
这些模块由 C++ 编写,属于非托管代码,负责 CLR 的启动、内存管理(GC)、线程调度等核心功能
 
  1.非托管入口点


  • CLR 的启动由非托管代码(C++)实现,入口模块为 mscoree.dll(Microsoft Component Object Runtime Execution Engine)。
  • mscoree.dll 负责加载 mscorwks.dll 或 mscorsvr.dll,具体取决于配置。
       1.显示配置 
   通过配置文件(app.config)指定
  1. <configuration>
  2.   <runtime>
  3.     <gcServer enabled="true"/>
  4.     <gcConcurrent enabled="true"/>
  5.   </runtime>
  6. </configuration>
复制代码
 

  • 或通过环境变量 COMPLUS_gcServer 设置为 1。
       2.隐式推断
               若未显式配置,CLR 根据进程类型自动选择:
                          控制台应用、WinForms/WPF 默认使用 Workstation
                          ASP.NET、Windows 服务等默认使用 Server(取决于宿主配置)。
        3.NET Framework 4.0 及之后:



    • mscorwks.dll 和 mscorsvr.dll 合并为 clr.dll,但两种 GC 模式(Workstation/Server)仍然保留。
    • 通过配置选择 GC 模式,而非直接依赖不同的 DLL。

 
       4.NET Core / .NET 5+
         完全重构的运行时(CoreCLR/CoreRT),不再区分 Workstation/Server 的 DLL。
         但 GC 模式(Workstation/Server)仍然存在,可通过配置选择:
  1. dotnet yourapp.dll --GCName=Server
复制代码
  1. Console.WriteLine($"当前GC模式: {(GCSettings.IsServerGC ? "Server" : "Workstation")}");
复制代码
            一般启用 Server GC 是利用多核并行性,同时在性能观察中,可以监控 GC 暂停时间,必要时调整 GCHeapCount 或 GCHeapAffinity。
 
 
 
2.目标场景


  • Workstation(工作站版本)

    • 优化目标:交互性(低延迟)和 单线程性能
    • 适用场景:客户端应用程序(如桌面应用、WinForms/WPF)、需要快速响应的场景。

  • Server(服务器版本)

    • 优化目标:高吞吐量 和 多线程并行性
    • 适用场景:服务器端应用程序(如 ASP.NET、后台服务)、多核 CPU 密集型任务。

Workstation GC:提供了一种默认的并发GC模式(当然这个是可以选择关掉)

  • 并发 GC(Concurrent GC):允许用户线程与 GC 线程交替执行,减少暂停时间。
  • 适合需要低延迟的交互式应用,避免界面卡顿
Server GC

  •  多堆并行回收

    • 为每个逻辑 CPU 核心分配独立的堆(Heap),减少线程竞争。
    • 使用专用 GC 线程(每个 CPU 核心一个线程),并行回收垃圾。

  • 适合高吞吐量的多线程服务,最大化 CPU 利用率。
线程池调度


  • Workstation

    • 线程池的线程创建策略更保守,避免过度占用资源。

  • Server

    • 线程池初始分配更多线程(与 CPU 核心数相关),适应高并发请求。

 

 

 3.分代GC:内存管理的基础结构

     1.核心设计
         分代模型是 .NET GC 的核心设计,基于以下假设:

  • 弱分代假设(Weak Generational Hypothesis):大多数对象生命周期短暂,存活时间较短。
  • 强分代假设(Strong Generational Hypothesis):存活时间越长的对象,越不容易被回收。
因此,.NET 将堆内存划分为三个代:

  • 第0代(Gen 0):存放最新创建的对象。
  • 第1代(Gen 1):存放从 Gen 0 晋升的存活对象。
  • 第2代(Gen 2):存放从 Gen 1 晋升的长生命周期对象。
     2.分代GC的工作流程

  • 新对象分配:所有新对象初始分配在 Gen 0。
  • Gen 0 回收

    • 当 Gen 0 满时触发回收。
    • 存活的对象晋升到 Gen 1。
    • 回收快速且频率高(通常仅需几毫秒)。

  • Gen 1 回收

    • 若 Gen 0 回收后 Gen 1 仍满,触发 Gen 1 回收。
    • 存活对象晋升到 Gen 2。

  • Gen 2 回收

    • 当 Gen 2 满时触发,回收耗时较长(可能数十到数百毫秒)。
    • 存活对象保留在 Gen 2。

      分代模型的优势在于减少扫描范围,避免每次回收都遍历整个堆
 
 
4.并发GC:减少暂停时间的执行策略

         并发 GC 是分代模型的一种补充优化,目标是最小化应用程序线程的暂停时间(Stop-The-World, STW)。
        其核心思想是:在 GC 回收过程中,允许应用程序线程继续执行
      1.并发GC的具体实现

      在 .NET 的 Workstation GC(工作站模式) 中:

  • 仅作用于 Gen 2 的回收

    • Gen 0/1 的回收时间极短,直接采用 STW 暂停。
    • Gen 2 的回收耗时较长,因此使用并发模式。

  • 并发阶段流程

    • 初始标记(Initial Marking):短暂暂停,标记根对象。
    • 并发标记(Concurrent Marking):应用程序线程与 GC 线程并发执行。
    • 重新标记(Final Marking):短暂暂停,修正并发期间对象状态变化。
    • 并发清理(Concurrent Sweep):回收不可达内存,应用程序线程继续运行。

        2.并发GC的局限性



    • 内存碎片:并发清理可能导致内存碎片化。
    • CPU 资源竞争:GC 线程与应用程序线程共享 CPU 资源。

        3.可以关闭并发GC

行为并发 GC(默认)非并发 GC(禁用并发)Gen 2 回收暂停时间较短(分阶段暂停)较长(完全暂停)CPU 资源占用GC 线程与应用线程共享 CPUGC 独占 CPU,回收更快完成适用场景交互式应用(如 UI 程序)批处理任务、后台服务(允许较长暂停)

              需要说明的是:NET5中是这样设
  1. / 设置延迟模式为 Batch(禁用并发 GC)
  2. GCSettings.LatencyMode = GCLatencyMode.Batch;
复制代码
 
     禁用并发 GC 的适用场景

        a. 高吞吐批处理任务

                例如数据转换、离线计算等任务,允许完全暂停以换取更快的 GC 完成速度。
              优势:减少 GC 线程与应用线程的 CPU 竞争,提高整体吞吐量。
       b. 内存密集型后台服务

             若服务对延迟不敏感,但需要快速释放内存。
             示例:日志处理服务、文件压缩服务。
      c. 调试与分析

              禁用并发 GC 可以使 GC 行为更可预测,便于调试内存问题。
 
 
 
5.服务器模式 GC 的核心设计

服务器模式 GC 的底层逻辑是:

  • 为每个逻辑 CPU 核心分配独立的堆(Heap),每个堆包含 Gen 0、Gen 1 和 Gen 2。
  • 为每个堆分配专用的 GC 线程,并行执行垃圾回收。
  • 共享大对象堆(LOH, Large Object Heap),所有堆共享同一个 LOH。
          在服务器模式下,Gen 2 的回收是并行的,但实现方式与 Gen 0/1 不同

  • 全局触发:当任意堆的 Gen 2 满时,触发全局 Gen 2 回收。
  • 多线程协同

    • 分段标记(Segment Marking):将 Gen 2 堆划分为多个逻辑段,每个 GC 线程负责一个段的标记。
    • 并行压缩(Parallel Compaction):多个线程并行移动存活对象,减少内存碎片。

  • 完全暂停(Stop-The-World)

    • Gen 2 回收期间,所有应用程序线程暂停。
    • 但 GC 线程之间并行工作,最大化利用多核 CPU。

 
 
 
6.总结:

1. 工作站模式(Workstation GC)

a. Gen 0/1 回收

<ul>STW(完全暂停):无论是否启用并发 GC,Gen 0/1 的回收均会完全暂停用户线程。

原因:Gen 0/1 回收极快(通常
您需要登录后才可以回帖 登录 | 立即注册