混合Println和Fmt.Println对堆栈增长的影响
在Go中,堆栈的分配和增长取决于函数的使用像 println() 和 fmt.Println().
Println() 与 Fmt.Println()
Println() 是编译器已知的内置函数,这意味着它的参数不会逃逸到堆中。相比之下,属于标准库的 fmt.Println() 被视为与任何用户定义函数一样。编译器无法保证其参数不会逃逸,因此这些参数分配在堆上而不是堆栈上。
对堆栈增长的影响
堆栈运行时空间不足,分配更大的堆栈。因此,堆栈分配的变量被移动,改变了它们的地址。发生这种移动是因为递归函数 stackCopy() 传递了一个重要参数(大小为 1024 的数组)。初始分配的堆栈不足,需要更大的堆栈并重新定位变量。
使用 fmt.Println() 时,编译器识别出参数 s 可能会逃逸并将其分配在堆上。因此,堆栈增长不会触发 s 的移动。
逃逸分析
要进一步了解此行为,可以利用“-gcflags '-m'”编译期间的标志,它公开了编译器的转义分析。在仅使用 println() 的情况下,分析表明 s 没有逃逸。相反,当混合 println() 和 fmt.Println() 时,编译器会推断 s 转义并将其分配在堆上。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3