要点:
1 Channel带不带缓冲
2 谁在发
3 谁在收
4 谁来关
5 关了没
Channel有buffer和没有buffer的特点
不带缓冲:要求收发两端都必须要有goroutine否则就是阻塞
有buffer:缓冲没满或者没空之前都不会阻塞,缓冲满了或者空了就会阻塞
没有初始化的channel为nil channel 发送和接收都会阻塞
向已经关闭的Channel发送数据会panic 接收数据会返回0
channel使用不当会导致goroutine泄露
1只发送不接受,发送者一直阻塞会导致泄露
2只接收不发送,接收值一直阻塞会导致泄露
3读写nil都会导致泄露
基本上可以说,goroutine泄露都是因为goroutine被阻塞之后没有人唤醒它导致的
解决方法:延迟机制,超过一定时间自动关闭;确定管理好发送和接收者避免阻塞的发生
channel与内存逃逸
内存分配:
分配到栈上:要知道分配到哪个栈上才会分配到对应的栈上,不需要考虑GC,性能与内存友好
分配到堆上:需要考虑GC
Channel传递指针一定会逃逸因为不知道目标地址无法分配到栈上
Channel发送步骤
1. 看是不是 nil channel,是的话直接阻塞
2. 看有没有被阻塞的接受者,有的话直接交付数据,返回
3. 看看缓冲有没有满,没有就放缓冲,返回
4. 阻塞,等待接收者来唤醒自己
5. 被唤醒,做些清理工作
Channel接收步骤
1. 看是不是 nil channel,是的话直接阻塞
2. 看有没有被阻塞的发送者,有的话直接从发送者手里拿,返回
3. 看看缓冲有没有数据,有就读缓冲,返回
4. 阻塞,等待发送者来唤醒自己
5. 被唤醒,做些清理工作