I'm a newbie to Go, coming from Node.JS.
In Node, if I run this:
function run(tick = 0) {
if (tick < 1000000) {
return run(tick + 1);
}
return 0;
}
console.log(run());
The program will crash because the maximum call stack size was exceeded.
If I do this in Go:
package main
import "fmt"
func run(tick int) (int) {
if (tick < 1000000) {
return run(tick + 1)
}
return 0
}
func main() {
fmt.Println(run(0))
}
This will run and print 0
to stdout.
My questions are:
Without any local variables, each function call takes up 48 bytes during the execution, and you are limited to less than 1MB for all local function frames. Each boolean and number variable takes 8 bytes of memory.
Default stack size varies between 320k and 1024k depending on the version of Java and the system used. For a 64 bits Java 8 program with minimal stack usage, the maximum number of nested method calls is about 7 000. Generally, we don't need more, excepted in very specific cases. One such case is recursive method calls.
In Go, goroutines do not have a fixed stack size. Instead they start small (with like 4KB), and grow / shrink when needed, seemingly giving the feeling of an "infinite" stack (of course it can't be truly infinite).
Yes, there is a limit. But this limit does not come from a call depth limit, but rather the stack memory limit. This limit is enforced by the Go runtime, but it is usually hundreds of MBs (or even a GB). On the Go Playground it's 250MB, which can be seen on this Go Playground Example.
On my local Linux 64-bit machine it's 1 GB.
Recommended reading: Dave Cheney: Why is a Goroutine's stack infinite?
Returning to your example: increasing the max recursion call to 1e9
will run out of the stack:
if (tick < 1000000000) { ... }
This will result in:
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x4b4730, 0xe)
/usr/local/go/src/runtime/panic.go:619 +0x81
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1054 +0x71f
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:480 +0x89
goroutine 1 [running]:
main.run(0xffffde, 0x0)
/home/icza/gows/src/play/play.go:5 +0x62 fp=0xc440088370 sp=0xc440088368 pc=0x483262
main.run(0xffffdd, 0x0)
/home/icza/gows/src/play/play.go:7 +0x36 fp=0xc440088390 sp=0xc440088370 pc=0x483236
main.run(0xffffdc, 0x0)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With