You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GC完成后使用dotnet-dump收集.NET 6 Windows服务转储?

解决.NET 6 Windows服务转储时GC进行中的问题

方案1:PowerShell脚本轮询GC状态后触发转储

编写脚本通过dotnet counters监控GC运行状态,等到GC暂停时立即调用dotnet-dump收集转储,避免捕获到GC执行中的状态。

步骤:

  1. 获取目标服务的PID(可通过Get-Process <服务进程名>查询)
  2. 执行以下脚本(替换PID为实际值):
$targetPid = 1234 # 替换为你的服务进程PID
$isGcRunning = $true

while ($isGcRunning) {
    # 每秒两次抓取GC占用时间计数器
    $counterResult = dotnet counters monitor --process-id $targetPid System.Runtime[GC%Time] --refresh-interval 0.5
    # 判断GC是否处于空闲状态(GC%Time为0表示当前无GC执行)
    if ($counterResult -match 'GC%Time\s+0') {
        $isGcRunning = $false
        # 生成带时间戳的转储文件
        $dumpFileName = "dump_$(Get-Date -Format 'yyyyMMdd_HHmmss').dmp"
        dotnet-dump collect --process-id $targetPid --output $dumpFileName
        Write-Host "转储文件已生成:$dumpFileName"
    }
    Start-Sleep -Milliseconds 500
}

方案2:自定义诊断工具等待GC完成后转储

编写轻量.NET控制台工具,利用.NET诊断API监听GC停止事件,在GC周期结束后自动生成转储。

核心代码示例:

using System;
using System.Diagnostics;
using Microsoft.Diagnostics.NETCore.Client;

class WaitGCAndDump
{
    static void Main(string[] args)
    {
        if (args.Length != 1)
        {
            Console.WriteLine("使用方式:WaitGCAndDump <目标进程PID>");
            return;
        }

        int pid = int.Parse(args[0]);
        var diagnosticsClient = new DiagnosticsClient(pid);

        // 订阅GC相关事件
        using var eventSession = diagnosticsClient.StartEventSession(new[] {
            new("Microsoft-Windows-DotNETRuntime", EventLevel.Informational, (long)ClrTraceEventParser.Keywords.GC)
        });

        Console.WriteLine("等待GC完成...");
        eventSession.EventStream.Subscribe(evt =>
        {
            // 捕获GC停止事件
            if (evt.EventName == "GCStop")
            {
                string dumpPath = $"dump_{DateTime.Now:yyyyMMdd_HHmmss}.dmp";
                diagnosticsClient.WriteDump(DumpType.Full, dumpPath);
                Console.WriteLine($"转储已生成:{dumpPath}");
                eventSession.Stop();
                Environment.Exit(0);
            }
        });

        Console.ReadLine();
    }
}

编译后在目标机器运行WaitGCAndDump <服务PID>,工具会自动等待GC完成后生成完整转储。

方案3:服务代码中添加GC稳定后的转储触发逻辑(若允许修改代码)

如果可以对服务代码做微小改动,可添加触发转储的方法,确保在GC完全完成后执行:

using System;
using System.Diagnostics;
using Microsoft.Diagnostics.NETCore.Client;

public static class DumpTrigger
{
    public static void CollectDumpAfterGC()
    {
        // 等待所有挂起的终结器执行完毕,确保GC周期收尾
        GC.WaitForPendingFinalizers();
        // 强制执行一次GC并等待完成,确保当前无GC运行
        GC.Collect();
        GC.WaitForPendingFinalizers();

        // 生成转储文件
        int currentPid = Process.GetCurrentProcess().Id;
        var client = new DiagnosticsClient(currentPid);
        string dumpFileName = $"dump_{DateTime.Now:yyyyMMdd_HHmmss}.dmp";
        client.WriteDump(DumpType.Full, dumpFileName);
    }
}

可通过自定义命令行参数、内部API接口或配置开关调用该方法,确保转储在GC稳定状态下生成。

内容的提问来源于stack exchange,提问作者Dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:25:18