Golang Go语言中关于内存的问题

发布于 1周前 作者 nodeper 来自 Go语言

Golang Go语言中关于内存的问题

我用 golang 写了一个 gtail https://github.com/chen19901225/gtail, 为什么居然要 12M 左右的内存,

感觉比 python 写的占用还多,感觉不科学呀?

关键我查不到就是把 python 的逻辑复制到 golang, 没有什么奇怪的操作呀

请大佬指点下为什么?

使用命令

go build 

./gtail --pattern=/tmp/*.log


更多关于Golang Go语言中关于内存的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

看了看 我的 16g 大内存笔记本, 这帖对我来说 可以略过了

更多关于Golang Go语言中关于内存的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我也是 16G 呀,但是 vagrant vbox 只分配了 6G,

不知道你 Python 怎么写的,看 go 的代码,内存占用最大的是 filepath.Glob,这个函数调用了*file.Readdirnames 会列出 /tmp 下面所有文件名。我在本机上试,/tmp 下面 2w 个文件,单独 Readdirnames 就占用 10M 内存……

更正一下,Readdirnames 占用了 2M,剩下的应该都是 runtime 内存(

我就是想它在不断的循环调用 glob 呀,因为如果是不断的调用 glob 的话,那么如果那个目录新加了文件,就会自动 tail 了,默认的 tail, 相当于了旨在第一次调用的时候,glob 了一下,这不是我想要的

不是说 golang 比 py 省内存吗,为什么会占 10M ?

10M 左右对 go 来说并不多.

就你这个程序, 我尝试编译跑了一下, 一个目录里只有两个文件, 无新写入, 内存占用在 7M 左右
用 pmap 看了下, 3M 多是从 binary 里映射出来的 (不用 urfave/cli 估计能少 2M). go 的 gc 要等到 heap 增长到一定 size 才会触发

GODEBUG=gctrace=1 ./gtail --pattern xxx

可以看到 log:

gc 1 .953s 0%: 0.055+0.85+0.016 ms clock, 0.44+0.50/0.67/0.21+0.13 ms cpu, 4->4->0 MB, 5 MB goal, 8 P

在程序运行 164s 后触发了第一次 gc, 回收了 4M 的 heap 内存, 但你看到的 rss 并不会直接减少, runtime 会复用这段内存, 所以最后 rss 稳定在 7M 多.

python 跑一个没任何变量分配的死循环也要占用 7M 多, go 不到 1M. 你没给出 python 的代码, 不好说.

并没有 go 一定比 python 省内存这种说法, 完全取决于你的 workload, python 的引用计数+mark&seep 方式, 在简单代码里完全可能比 go 的 gc 省内存.

好吧,我还以为 golang 内存很小呢,4-5M 呢

在Golang(Go语言)中,内存管理是一个核心且高效的机制,主要依赖于垃圾回收器(Garbage Collector, GC)。以下是一些关于Go语言中内存问题的关键点:

  1. 自动内存管理:Go语言提供了自动内存管理功能,开发者无需手动分配和释放内存。垃圾回收器会定期检查并回收不再使用的内存,从而减少了内存泄漏的风险。

  2. 逃逸分析:编译器在编译时会进行逃逸分析,以确定变量是否会在函数调用后继续被引用(即“逃逸”到堆上)。对于未逃逸的变量,编译器会将其分配在栈上,以提高内存访问速度和减少垃圾回收压力。

  3. 内存泄漏:虽然Go有垃圾回收机制,但不当的闭包使用、全局变量引用、未关闭的goroutine等都可能导致内存泄漏。因此,开发者应注意资源管理,如及时关闭文件、网络连接和数据库连接等。

  4. 性能调优:对于高性能需求的应用,开发者可以通过调整垃圾回收器的参数(如GOGC环境变量)来优化内存使用。此外,使用内存池、对象重用等技术也可以进一步减少内存分配和回收的开销。

  5. 工具支持:Go语言提供了多种工具(如pprof、trace等)来帮助开发者分析内存使用情况,识别性能瓶颈和优化点。

总之,虽然Go语言的内存管理机制相对简单和高效,但开发者仍需关注内存使用,通过合理的编程习惯和工具支持来确保应用的性能和稳定性。

回到顶部