go的COM调用由GC收集数据,并将已用内存归零

go的COM调用由GC收集数据,并将已用内存归零,com,go,Com,Go,我有一个go程序,它执行WMI查询,然后将数据转换回go land数据结构(使用该方法)。每隔一段时间,go的GC就会出现,将一些看似随机的内存部分核化为0s,造成可怕的破坏 我正试图找出到底是什么导致了这个问题,我相信下一步就是了解COM调用过程中发生了什么。我目前的理解是: 使用来自进程的WMI查询调用COM 操作系统执行查询并将结果写入进程拥有的某个内存位置 该位置是从COM调用返回的,然后我可以访问并序列化它 这是怎么回事?Windows如何选择该内存位置,使其不会覆盖现有数据?每个CO

我有一个go程序,它执行WMI查询,然后将数据转换回go land数据结构(使用该方法)。每隔一段时间,go的GC就会出现,将一些看似随机的内存部分核化为
0
s,造成可怕的破坏

我正试图找出到底是什么导致了这个问题,我相信下一步就是了解COM调用过程中发生了什么。我目前的理解是:

  • 使用来自进程的WMI查询调用COM
  • 操作系统执行查询并将结果写入进程拥有的某个内存位置
  • 该位置是从COM调用返回的,然后我可以访问并序列化它

  • 这是怎么回事?Windows如何选择该内存位置,使其不会覆盖现有数据?

    每个COM对象都使用AddRef()和Release()进行引用计数。也许您需要一个额外的AddRef()来延长它的使用时间


    我从示例代码中看到有很多延迟的发布调用。这很好,因为我们希望在main的末尾释放对象。在您的程序中,您可能希望将发布推迟更长时间(但是,我不知道go或defer到底做了什么)

    COM对象通常是在堆上分配的。在这之后,它们被引用计数。位置由正常的运行时堆选择。通常,在代码不再引用对象之前,对象不会被GC’d(并因此被覆盖)。这里面有一些引用计数问题。正如你们中的一些人所建议的,这似乎是Go没有保留从COM返回的对象指针的问题。我已经用最新的研究更新了github问题:我将测试ref计数,看看这是否是问题所在。不过,我怀疑这是否是原因,因为如果我禁用go GC(或编译并作为32位go应用程序运行),那么一切都正常工作。go对象是否引用了它们在GC上发布的COM对象?如果是这样的话(1),go对象可能需要引用某个对象来保持它的存在——例如,如果COM对象是唯一引用go对象的对象,那么go GC可能不知道它。(2) 也许还需要一个额外的AddRef,并且GC的d对象不应该是最后一个版本。Ref计数似乎不是问题。在删除释放调用,然后添加AddRef调用之后,问题保持不变。WMI是否需要单线程COM单元STA与MTA?如果是这样,您需要启动一个线程,使其成为STA,并从那里执行所有WMI访问。go例程将自身锁定到一个线程init'd COM,然后通过该线程发送所有WMI查询。查看我对这个问题的新评论,了解一些进展。这看起来好像没有对COM数据的引用,因此它们得到了GCd,但仍在使用。