为什么CGO_ENABLE会对虚拟内存产生如此大的影响?
我有一个写在Golang上的小守护进程,它在循环中工作并做一些事情。我发现,当使用CGO_ENABLE=1或CGO_ENABLE=0编译守护进程时,守护进程的行为会有所不同。例如,当CGO_ENABLE=1(默认值)时,程序的VSZ在短时间内(一小时内)膨胀到1-2GB。启用CGO_=0时,VSZ在长时间内(几天内)是相同的。请看下面的数字: CGO_ENABLED=1(守护进程已工作5分钟) CGO_ENABLED=0(守护进程已工作约30小时) 守护进程不使用依赖于CGO的包或函数。其他Go编写的程序也表现出同样的行为。我知道VSZ和RSS之间的区别,我很感兴趣,这种行为的本质是什么?为什么使用CGO_ENABLED=1编译的程序要求从内核提供这么多内存为什么CGO_ENABLE会对虚拟内存产生如此大的影响?,go,Go,我有一个写在Golang上的小守护进程,它在循环中工作并做一些事情。我发现,当使用CGO_ENABLE=1或CGO_ENABLE=0编译守护进程时,守护进程的行为会有所不同。例如,当CGO_ENABLE=1(默认值)时,程序的VSZ在短时间内(一小时内)膨胀到1-2GB。启用CGO_=0时,VSZ在长时间内(几天内)是相同的。请看下面的数字: CGO_ENABLED=1(守护进程已工作5分钟) CGO_ENABLED=0(守护进程已工作约30小时) 守护进程不使用依赖于CGO的包或函数。其他Go
我希望答案不是“别担心,VSZ只是一个虚拟内存,实际上它不被进程使用”这样的形式 您可能知道,“reference”Go实现(历史上称为“gc”;可从下载)的编译器默认生成静态链接的二进制文件。这意味着,这些二进制文件只依赖于操作系统内核提供的所谓“系统调用”,而不依赖于操作系统(或第三方)提供的任何共享库 在基于Linux的平台上,这并非完全正确:在默认设置(基于Linux for Linux构建,即不交叉编译)中,生成的二进制文件实际上与
libc
并使用libpthread
(间接地,通过libc
)
这种“扭曲”来自Go标准库必须与操作系统交互的两个需求:
net
包需要此解析os
包所需要的- Linux本身(即内核,而不是整个操作系统)不提供任何执行这些任务的方法
- 从永远以来,任何典型的类UNIX系统都使用一种称为“NSS”的特殊工具来提供这两种任务, 哪一个是“名称服务开关” NSS提供可插拔的模块,可用于 作为提供特定类型查询的数据库:DNS、用户/组数据库等(如“服务”的知名名称等)。一个被认为是相当普遍的例子 用户/组数据库的非标准提供程序是本地数据库 与LDAP服务器联系的服务
libc
(在不太典型的系统上,它可能由
单独的共享库,但变化不大)
因为,libc
是一个相当稳定的
库的API(它甚至提供了版本符号
作为未来的证明),Go作者正确地决定,针对libc
链接以导入符号的最小子集(主要是getaddrinfo
,getnameinfo
,getpwnam_r
等)是可以的
默认情况下,99%的情况下都是安全的,
如果不是,那些必须处理这些案件的人通常
我知道该怎么办
因此,默认情况下启用了cgo
,并用于使用NSS实现这些查找
如果禁用了cgo
,则Go编译器将改为在其自身中链接
回退实现,尝试模仿
完整的NSS实现(即解析/etc/resolv.conf
并使用其中的信息直接查询此处列出的DNS服务器;解析/etc/passwd
和/etc/group
以服务于用户/组数据库查询)
如你所见,在defult的案例中
被映射到,并且libc
- 它被初始化并使用一些内存来满足自己的需要- 例如NSS调用返回的数据的明显缓存
cgo
的情况下,上述两种情况不会发生。您有更多静态链接的stdlib代码,但就RSS的总体累积使用量而言,默认情况似乎仅优于后者
考虑研究
为了增加乐趣;-)
不要与Mozilla混淆。您可以比较/proc/$pid/maps来找出答案。VSZ不是“内核提供的内存”。它毕竟是虚拟的,包括交换内存、与其他程序共享的内存、内存映射文件等。同样,/proc/$pid/maps有一个故障。@Peter,谢谢你,但是我上面提到了我知道什么是VSZ。也许我用了一点不正确的描述。此外,地图文件是一个众所周知的为我。我问过,为什么启用CGO_会影响程序所描述的行为,而不是VSZ。你是在Linux上尝试这个吗?是的,在Linux上。谢谢,听起来很合理。还有,关于
$ grep -E 'VmSize|VmRSS' /proc/14916/status
VmSize: 1084052 kB
VmRSS: 12524 kB
$ grep -E 'VmSize|VmRSS' /proc/15160/status
VmSize: 110232 kB
VmRSS: 9756 kB