2019-3-26更新:
这个bug已经在go1.12修复了
=======
之前从一个朋友手上拿到一份代码,运行起来会不停吃内存,但是从代码本身看,好像又不应该:
package main
type Node struct {
next *Node
payload [64]byte
}
func main() {
curr := new(Node)
for {
curr.next = new(Node)
curr = curr.next
}
}
类似一个单链表,每次申请一个节点接在尾部,然后curr指向最后一个节点,按理说在for循环中,curr引用的只有最后一个节点,而最后一个节点的next是nil,不引用任何其他数据,所以前面的节点应该都会被gc释放才对,但测试结果是内存不停涨。虽然没仔细分析过源码,但还是基本了解go的gc做法的,不可能是由于不及时导致
之后打印了相关内存地址才反应过来,是第一个Node的new分配在栈上了,go编译器会对代码做逃逸分析,如果在函数中new分配一个小对象,而且这个小对象不会逃逸出去,则可以直接将其分配到栈上,所以上面代码在优化后相当于:
func main() {
var n Node
curr := &n
for {
curr.next = new(Node)
c