没有单独的运行时或VM的GC如何工作?

My understanding is that executables of applications written in Go can stand alone without the need of Go installed in the machine.

Normally my understanding is that the GC (Garbage Collection) is handled by a VM. In this case, if the application is running independently without such a runtime how is GC handled?

A help on this and the documentation on the same would be nice.

Binaries in golang have no external dependencies as they are directly compiled in. Unlike a C/C++ binary which typically requires dynamic linking, golang binaries do not require this by default.

https://golang.org/doc/faq#runtime

This allows you to copy, scp , rsync, etc your binary across to any machine of the same architecture type. For example, if you have a compiled binary on Ubuntu then you can copy that binary across to any other Ubuntu machine. You would have to cross-compile your binary for MacOS in order to do that, but again you can build on any operating system.

https://golang.org/doc/install/source#environment

my understanding is that the GC (Garbage Collection) is handled by a VM.

In the case of a typical VM supporting programming language featuring GC, (the compiled form of) a program written in that language is literally managed by the VM: the VM runs the code of the program and intervenes periodically to perform the GC tasks.

The crucial point is that each program running in such a VM may consider its VM as a part of its execution environment.

Another crucial point is that such VM represents the so-called runtime system for the so-called execution model of that programming language.

In this case, if the application is running independently without such a runtime how is GC handled?

Quite similar to the VM case.

Each Go program compiled by the stock toolchain (which can be downloaded from the official site contains the Go runtime linked with the program itself. Each compiled Go program is created in a way that when the program runs, the program's entry point executes the runtime first which is responsible for initializing itself, then the program, and once this is finished, the execution is transferred to the program's main().

Among other things, the initialized Go runtime continuously runs one or more pieces of code of its own, which includes the goroutine scheduler and the GC (they are tightly coupled FWIW).

As you can see, the difference from the VM is that in that case the runtime is "external" to the running program while in the (typical) case of Go programs it's "along" the running program.


Nothing in the Go language specification mandates the precise way the runtime must be made available to the running program.

For instance, Go 1.11 can be compiled to WASM, and the runtime is partially provided by the linked-in code of the Go runtime and partially—by the WASM host (typically a browser).

As another example, GCC features a Go frontend, and contrary to the "stock" Go toolchan, and on those platforms where it's possible, GCC supports building Go in a way where their compiled forms dynamically link against a shared library containing most of the Go runtime code (and the code of the standard library). In this case, a compiled Go program does not contain the runtime code but it gets linked in when the program is being loaded and then it also works in-process with the program itself.

It's perfectly possible to implement an execution model for Go programs which would use a VM.