C代码是否喜欢Go-GC';s的碎片化预防策略?

C代码是否喜欢Go-GC';s的碎片化预防策略?,go,garbage-collection,swig,cgo,virtual-address-space,Go,Garbage Collection,Swig,Cgo,Virtual Address Space,纠正了错误含义: Golang的GC执行虚拟地址空间碎片整理碎片预防策略,这使程序能够运行很长时间(如果没有的话) 但C代码(cgo或SWIG)似乎无法更新内存指针,以防它们移到别处。从这些策略中获益 这是真的吗?C代码是否会从Golang的虚拟地址空间碎片整理碎片预防中获益,并最终获得碎片 如果那是假的,怎么办 另外,C代码加载的任何DLL代码(例如Windows DLL)会发生什么情况 (该问题已更新以纠正我的错误假设)视情况而定 C代码需要的内存可以通过Go分配,它的指针可以传递给C代码。

纠正了错误含义:

Golang的GC执行虚拟地址空间碎片整理碎片预防策略,这使程序能够运行很长时间(如果没有的话)

但C代码(cgo或SWIG)似乎无法更新内存指针,以防它们移到别处。从这些策略中获益

  • 这是真的吗?C代码是否会从Golang的虚拟地址空间碎片整理碎片预防中获益,并最终获得碎片

  • 如果那是假的,怎么办

  • 另外,C代码加载的任何DLL代码(例如Windows DLL)会发生什么情况

  • (该问题已更新以纠正我的错误假设)

    视情况而定

    C代码需要的内存可以通过Go分配,它的指针可以传递给C代码。在这种情况下,C代码将受益于Go的碎片预防策略


    DLL代码也是如此,因此,如果DLL函数不自己分配工作内存,也可以为它们分配工作内存。

    我担心您可能会在多个级别上混淆问题

    首先,在生产级Go代码中调用C通常从一开始就是不可能的:速度很慢;与进行系统调用一样慢-在大多数情况下,它实际上是作为一个系统调用工作的:需要从Go堆栈切换到C堆栈,并让碰巧执行Go代码的OS线程将
    cgo
    调用锁定到该线程,即使C端有什么阻塞

    这并不是说您必须避免调用C,但这意味着您需要预先考虑并衡量这一点。可能正在设置一个worker goroutine池,将需要进行C调用的任务分散到其中

    第二,你对记忆的担忧可能是毫无根据的;让我解释一下

    在当代系统中,虚拟内存的碎片化应该不是一个问题 通常用于运行Go程序(我指的是
    amd64
    等)。 这在很大程度上是因为分配虚拟内存不会强制操作系统 要实际分配物理内存页,只会发生后者 当虚拟内存被使用时(即,在某个地址访问) 恰好指向已分配的虚拟内存区域)。 所以,不管你想不想,你确实有物理内存碎片问题 不管怎样,事情正在得到解决 在操作系统和CPU级别使用多层地址转换 表(和TLB缓存)

    第三,你似乎陷入了一个常见的投机陷阱 如何在加载而不是编写高度简化的 对计划进行建模,并检查其在预计产量下的表现 负载也就是说,您认为分配C内存会出现问题 然后幻想这一切都不起作用

    考虑到产量,我认为你的担心是没有根据的 用C和C++编写的代码,在硬负载下工作。 最后,C和C++程序员开辟了通向高性能的途径。 内存管理很久以前就有了。典型的解决方案是使用自定义 显示最多的对象的池分配器 典型负载下的分配/解除分配流失。用这个办法,, 在C端分配的内存在整个生命周期中基本上是稳定的 你的计划

    TL;DR

    编写一个模型程序,将估计的负载放在上面,然后查看它的行为。 然后分析内存有什么问题(如果有),以及
    然后才开始攻击它们。

    你从哪里得到Go GC进行碎片整理的印象?我很想知道什么是“虚拟地址空间碎片整理”。哦,你的意思可能是Go的GC正在压缩?然后是否,当前(v1.10)和未压缩之前。运行时维护多个区域以分配不同大小类的对象;这些区域称为“跨度”,只有当某个跨度中没有正在使用的对象时,该跨度才会消失。但是AFAIK目前GC不能跨(相同大小的)跨度移动对象。首先,它是一种系统编程语言,用于编写服务器内容,这些内容必须能够在繁重的工作中运行几天,并且不能定期终止和重新执行。如果没有包括碎片整理在内的适当(完整)垃圾收集,Golang将成为系统编程和编写服务器的垃圾。第二,我肯定我在什么地方读过书,正在寻找它。:)“碎片整理”意味着移动活动指针,而GC不这样做。Go依赖于一个分配方案,该方案一开始几乎不会导致碎片化。我不明白如果Go GC这样做,C会有什么好处,因为C不使用GC(而且它一开始使用不同的分配器。tcmalloc与Go分配器类似,尽管Go有很多分歧),选民应该描述他们的想法,因为我不明白他们对我的想法有什么看法,他们有什么问题。(首先)谢谢。我不知道。我试图补偿调用动态编译DLL代码的解释。你的评论对我很有用。(二)谢谢。我非常了解MMU设计和内存随需应变方法。我读了几遍,但是我没有弄清楚我对虚拟地址空间碎片和物理地址空间碎片之间的关系。(三)非常感谢。你是对的,但我担心的是,因为我认为服务器的东西通常永远不需要重新执行,所以我想确保它是100%碎片容忍的。几个月前,我在一段时间后回到它,然后我也理解了第二部分,并选择它作为答案。现在,我也更好地意识到第三部分的重要性,我发现这绝对是真的。我希望我最好拥抱一下