sha*_*rok 5 pointers global-variables go
我只是在玩 Go 接口和结构,突然发现一些对我来说很奇怪的东西。情况是这样的:
https://play.golang.org/p/FgvRFV9Lij9
package main
import (
"fmt"
)
func main() {
scopedInt := 100
fmt.Printf("%p\n", &scopedInt)
globalInt = 100
fmt.Printf("%p\n", &globalInt)
}
var globalInt int
Run Code Online (Sandbox Code Playgroud)
输出:
0xc0000ba010
0x57b2a8
Run Code Online (Sandbox Code Playgroud)
地址的值无关紧要。关键是为什么第一个地址的位数比第二个多?
我想我错过了关于 Go 中全局变量概念的一点。
地址的“长度”相差很多位数,因为这些变量分配在内存的不同区域,它们具有不同的偏移量(起始位置)。
scopedInt
可能会在堆上分配,因为它从main()
(其地址被传递到fmt.Printf()
)“转义” ,而globalInt
是包级变量,因此将分配在固定大小的段之一中,即数据段。
只要地址指向有效的内存区域,地址的“长度”就无关紧要。Go 有自动内存管理,所以除非你接触 package unsafe
,否则你不必担心地址和指针是否有效。
要阅读有关内存管理的更多信息,请参阅Doug Richardson:转到内存管理。引用它:
什么去哪里?
Go 编程语言规范没有定义项目将被分配到哪里。例如,定义为 的变量
var x int
可以在堆栈或堆上分配,并且仍然遵循语言规范。同样,p
in指向的整数p := new(int)
可以分配在堆栈或堆上。但是,某些要求会在某些条件下排除某些内存选择。例如:
- 数据段的大小在运行时不能改变,因此不能用于改变大小的数据结构。
- 堆栈中项目的生命周期按它们在堆栈中的位置排序。如果堆栈的顶部是地址 X,则 X 之上的所有内容都将被释放,而 X 之下的所有内容将保持分配状态。由函数分配的内存如果被函数范围之外的项引用,则可以转义该函数,因此不能在堆栈上分配(因为它仍在被引用),也不能在数据段中分配(因为数据段不能在运行时增长),因此它必须在堆上分配——尽管内联可以删除这些堆分配中的一些。
归档时间: |
|
查看次数: |
174 次 |
最近记录: |