3 ms·
> I'm not familiar with the implementation of Go, but at least this program didn't explode the stack: It does, it's just that Go is so slow printing to the con
by sevenelfen 13y ago
> I'm not familiar with the implementation of Go, but at least this program didn't explode the stack:
It does, it's just that Go is so slow printing to the console that it would take years to run out of stack space. If you redirect to null it will use up all your memory and swap space in a few minutes:
./main > /dev/null
In most other languages this same code would run for a short time and then abort after exhausting the stack. This is the best behavior since algorithms that use unbounded memory are where you certainly must handle out of memory errors and set limits; using too much stack space is an error that should be caught quickly not postponed. Go on the other hand uses a growable stack, so the code you gave will use up all available memory and swap before finally crashing.
Go uses a growable stack so that programs can use many goroutines on 32-bit machines. This is bad for performance due to extra checks on calling function to see if the stack needs to be grown or shrunk, the overhead to actually do that, and less efficient use of cpu data cache. It makes it complicated to call functions from any other language. It seems like any modern language should work best on 64-bit and make trade-offs for 32-bit, not the other way.
- Evbn 13y agoGo uses a growable stack so that each goroutine's stack consumes less memory,not less address space.
- cmccabe 13y agoYou are mistaken. You don't need extra checks to determine when to grow the stack. You just need to leave some unmapped space after the stack and correctly handle a SIGBUS error. There is no extra overhead above what the operating system is already doing. Growable stacks aren't about getting optimal performance on 32 bit architectures. That is explicitly a non-goal of Go. They're about minimizing memory consumption for goroutines which don't use very much stack space, which is expected to be most goroutines. You can't have hundreds of thousands of goroutines if you have a high fixed amount of memory per goroutine. As for your argument that growable stacks make it harder to determine program correctness, it seems like nonsense to me. I could make the same arguments about heap space, but nobody thinks a low fixed limit on heap sizes is a great idea. If you want to test your program under low memory conditions, try mlocking a lot of memory and then running your program. Alternately you could try something involving cgroups or virtual machines.