当程序在golang中退出时,泄漏的内存是否被释放? [重复]
This question already has an answer here:
Before you claim a repeat question, I've read all those answers, but my question is focus to golang specific. With the golang proverb Don't communicate by sharing memory; share memory by communicating I wonder if there is a different by how golang manage the memory
</div>
此问题已经存在 在这里有一个答案: p>
-
程序退出时是否释放了泄漏的内存?
6个答案\ r
span>
li>
ul>
div>
在您声明重复问题,我已经阅读了所有这些答案,但我的问题是关注golang 使用golang谚语不要通过共享内存进行交流; 通过交流共享内存我想知道golang管理内存的方式是否有不同 p> div>
It appears you should refine your knowledge of how contemporary computer systems work—this may help working with languages such as Go, which are reasonably "closer to the metal" than some other mainstream solutions.
The thing is, the commodity platforms current Go runs on (except maybe WebAssembly—which runs on a high-level VM typically provided by a web browser) do two things related to the problem in question: fully "contain" the processes they're executing, and provide to them the so-called virtual memory management.
The former means a process running by the kernel of a commodity OS (Linux- or *BSD-based, Windows, Mac OS X etc) has no way to do anything useful without asking the underlying kernel to do that on behalf of that process. That is, the process does not actually allocate a memory or open a file or send bytes over a TCP socket—it asks the kernel to do so.
As a result, the kernel has full and exact account of all the resources allocated to each of the processes it manages. Consequently, when a process finishes executing for some reason, the kernel cleans up after it: closes file and socket descriptors which are still open, deallocates other resources and reclaims the memory which was committed to the process.
So the direct answer to your question is: of course, yes, and this does not in any way depend on how a process was implemented (that is, has it been written in C or in Go or in Java—and hence was run by the Java VM and compiled on the fly from the byte codes to real CPU instructions, or in JavaScript and executed by Node.js, or in Python—and hence the kernel wasn't actually executing your Python code but actually the Python interpreter's code, and so on and so on)—the kernel does not even "see" all these differences as it executes CPU instructions and performs the syscalls made by the processes (again, using CPU instructions).
The remaining part, which is only tangentially related to the essence of your question, but anyway may be helpful to think about is that of memory management.
The thing is, if we consider a process executing a program written in Go which is running on one of operating systems Go supports, there exist two levels of memory management:
- The low-level, provided by the kernel, and
- The high-level, provided by the Go runtime (which is linked to any running program written in Go).
The Go program asks the Go runtime which powers it to allocate memory, when needed, and the garbage collector, which again is a part of the Go runtime, from time to time reclaims the memory which got unused back to the memory pool maintained by the runtime. In essence, the memory which gets "freed" while a Go program is running stays within the program, and when it is needed again, the Go runtime will try to allocate it from its pool.
Only when the Go runtime's memory manager has not enough free memory, will it reach for the OS and allocate memory there—thus engaging that another layer of memory management.
Surely, the memory does not only flow from the kernel to the Go runtime: the latter has a mechanism to mark memory pages which stay free for too long as unused so that the kernel is free to reclaim them back when it sees fit (typically when the system gets under a memory pressure).
I'd say, you should read a book or two on how a typical operating system works.