我们有一个用 Go 编写的监控代理,它使用许多 goroutine 从 WMI 收集系统指标。我们最近发现,当 go 二进制文件在 Server 2016 或 Windows 10(也可能在其他使用 WMF 5.1 的操作系统上)运行时,该程序正在泄漏内存。在创建了一个最小的测试用例来重现该问题之后,似乎只有在您对 ole.CoInitializeEx 方法进行大量调用时才会发生泄漏(WMF 5.1 中可能发生了一些变化,但我们无法使用 python comtypes 包重现该问题在同一系统上)。
我们在我们的应用程序中将 COINIT_MULTITHREADED 用于多线程单元(MTA),我的问题是:因为我们从各种 goroutine 发出 OLE/WbemScripting 调用,我们需要在启动时调用 ole.CoInitializeEx 一次还是在每个 goroutine 中调用一次?我们的查询代码已经使用runtime.LockOSThread来防止调度程序在不同的 OS 线程上运行该方法,但是 MSDN 上关于CoInitializeEx的注释似乎表明它必须在每个线程上至少调用一次。我不知道有什么方法可以确保新的 goroutine 在已经初始化的 OS 线程上运行,因此多次调用 CoInitializeEx 似乎是正确的方法(并且在过去几年中运行良好)。
我们已经重构了代码以在专用的后台工作程序上执行所有 WMI 调用,但我很想知道我们的原始代码是否应该在启动时只使用一个 CoInitializeEx 而不是每个 goroutine 一次。