1.make和new的区别
详细见:https://studygolang.com/articles/3496
func new(Type) *Type:new的作用是返回一个指向类型的指针
func make(Type, size IntegerType) Type :make 的作用是为 slice, map 或者 channel 初始化,并且返回这个类型
2.栈和堆(与操作系统的理解不同
对于语言来说,代码声明的变量new、malloc如果在堆上,按操作系统理解,我只能自己释放,但我如果忘了呢?——>语言内存管理机制——>变量分配在堆上还是栈上不是由是否new/malloc决定,而是通过编译器的“逃逸分析”来决定。
逃逸分析的作用:判断变量会不会分配到堆上
1)如果分配到栈上,待函数返回资源就被回收了
2)如果分配到堆上,函数返回后交给gc来管理该对象资源
总结
指针必然发生逃逸的三种情况:
在某个函数中new或字面量创建出的变量,将其指针作为函数返回值,则该变量一定发生逃逸(构造函数返回的指针变量一定逃逸);
被已经逃逸的变量引用的指针,一定发生逃逸;
被指针类型的slice、map和chan引用的指针,一定发生逃逸;
必然不会逃逸的情况:
指针被未发生逃逸的变量引用;
仅仅在函数内对变量做取址操作,而未将指针传出;
有一些情况可能发生逃逸,也可能不会发生逃逸:
将指针作为入参传给别的函数;这里还是要看指针在被传入的函数中的处理过程,如果发生了上边的三种情况,则会逃逸;否则不会逃逸;
逃逸分析:https://www.jianshu.com/p/7571d3d0c12d
https://zhuanlan.zhihu.com/p/91559562
https://studygolang.com/articles/25902
3.栈中分配的变量,出栈的时候不会被释放吗?
func newInt *int {
var i int
return &i
}
someInt := newInt()
golang 和 c 语言不一样,栈区分配的存储空间不会随着函数的返回而释放,局部变量地址所占据的存储空间会生存下来。
个人推测,释不释放跟golang的GC有关系,记得golang用的是跟OC一样的基于引用计数的GC方案。所以即使是在函数内部alloc的,如果return回去了编译器会将这个对象的引用计数+1导致不会被GC回收。以上都是推测,待验证。
在Go中变量或者对象的保存不一定必须在栈或者堆中的,Go语言会根据变量在函数中的生命周期有关系,如果变量仅在函数中引用,那么就会保存在栈中,函数结束变量从栈中移除。如果函数中的变量不只是在函数中使用,比如列子中的,那么会将变量保存在堆中,所以例子中的变量是可以返回的,这就是Go的变量逃逸。