Why my Go program creates another Go process with the name of an open file, and why it's so big?

huangapple go评论90阅读模式
英文:

Why my Go program creates another Go process with the name of an open file, and why it's so big?

问题

我有一个大约2MB的大.json文件。我正在使用这段代码来读取json,稍作修改:

func main() {
    pages := getPages()
    for {

    }
    for _, p := range pages {
       fmt.Println(p.toString())
    }
}

如你所见,我加了一个无限循环,这样我就可以让程序在读取进程的RAM大小时等待。当我去读取时,我发现有两个Go程序在运行。我只是执行了

go run myfile.go

但是然后我得到了两个二进制文件:一个名为go,另一个是文件名去掉.json部分的。go二进制文件大约有5MB,但是另一个有36MB...

为什么Go会创建一个带有文件名的另一个进程?它是用来保存文件以便我读取吗?为什么会这样?据我所知,文件读取应该由操作系统处理。为什么它的大小与.json文件的大小相比如此之大?

另外,当getPages()返回时,文件对象和json对象不应该因为Go的垃圾回收机制而从内存中删除吗?

英文:

I have a big .json file that has about 2mb. I'm using this code to read the json, with a little modification:

func main() {
    pages := getPages()
    for {
        
    }
    for _, p := range pages {
       fmt.Println(p.toString())
    }

As you can see, I've put an infinite loop so I could make the program wait while I read the process's RAM size. When I've gone to read it, I've found 2 go programs running. I just did

go run myfile.go

but then I got 2 binaries: one named go, and the other with the name of the file without the json part. The go binary has like 5mb, but this one has 36mb...

Why does go creates another process with the name of the file? Is it where it holds the file so I can read? Why it does that? As far as I know, the file reading should be handed by the OS. And why it's so big compared to the .json size?

Also, shouldn't, when getPages() return, both the file object and json object be deleted from memory because of the go's garbage collector?

答案1

得分: 4

为什么Go会创建一个带有文件名的新进程?

实际上并不是Go创建了新进程,而是你自己创建的。当你执行go run main.go时,你正在运行Go程序,它会将你的main.go编译为一个不同的可执行文件(你还记得Go是一种编译语言,生成本机可执行文件吗?),然后执行这个第二个可执行文件。你告诉Go工具这样做,它按照你的指示执行。如果你不喜欢这样的行为,可以使用go build -o whatever; ./whatever命令。

此外,当getPages()返回时,文件对象和JSON对象应该被Go的垃圾回收器从内存中删除,对吗?

是的,实际上确实会这样。只是你尝试检查的方式不可观察到。Go中的内存管理是复杂的,与操作系统的内存管理相互作用也很复杂(并且与操作系统相关),而操作系统的内存管理也很复杂。

简单来说:Go的垃圾回收器会收集无引用的对象,但该内存不会作为“返回”给操作系统,因为从操作系统“返回”和“重新获取”内存是一项非常昂贵的操作,除非需要,否则内存不会“返回”给操作系统。

如果你对内存管理的细节感兴趣,可以在Stack Overflow或网络上搜索“go does not release memory”来了解更多信息。

英文:

> Why does go creates another process with the name of the file?

It doesn't. You did. When you do go run main.go You are running the go program which compiles your main.go to a different executable (you remember that Go is a compiled language producing native executables?) and executes this second executable. You told the go tool to do so and it behaves as told. If you do not like that: go build -o whatever; ./whatever.

> Also, shouldn't, when getPages() return, both the file object and json object be deleted from memory because of the go's garbage collector?

Yes and that actually happens. It just isn't observable in the way you tried to check it. Memory management in Go is complicated and the interplay with the memory management of the OS is complicated (and OS dependent) and OS memory management is complicated too.

Very roughly: The unreferenced objects are collected by the Go GC but that memory is not "returned" to the OS as "returning" and "re-acquire" memory from the OS is a very expensive operation, so memory is not "returned" to the OS (unless needed).

Search SO or the web for "go does not release memory" if you think the gory details of memory management are of interest to you.

huangapple
  • 本文由 发表于 2017年2月15日 14:01:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/42241774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定