Defer底层是一个名为_defer的结构体
若干个_defer结构体构成链表
_defer结构体在内存的分配位置
分配方式分为3类:堆上动态分配、栈上动态分配、open-coded的栈上静态分配
堆上动态分配
一个函数有几个defer方法是动态的、不确定的,因此链表长度不定,一开始就干脆设计成分配在堆上
栈上动态分配
后来发现堆上内存频繁分配和回收,就改成往栈上分,这样可以自动随着栈退出而回收内存(当然栈空间不够的话还是往堆上分配)
open-coded的栈上静态分配
再后来,继续优化。对于函数内一定数量内的defer 方法,使用defer bit 来cover 住所有可能的情况,从而将动态的defer【静态化】,这样在编译时,就可以把defer的逻辑插入函数体内一起被编译
多个defer,为什么后defer先执行
本质上是因为后来的_defer总是被添加到_defer链的头部,而当执行_defer链的时候是从链表头开始向后依次执行
参考https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-defer/
网友评论