15 lines
1.6 KiB
Markdown
15 lines
1.6 KiB
Markdown
|
### 内存占用
|
|||
|
- 创建一个 goroutine 的栈内存消耗为 2 KB(Linux AMD64 Go v1.4后),运行过程中,如果栈空间不够用,会自动进行扩容。
|
|||
|
- 创建一个 thread 为了尽量避免极端情况下操作系统线程栈的溢出,默认会为其分配一个较大的栈内存( 1 - 8 MB 栈内存,POSIX Thread),而且还需要一个被称为 “guard page” 的区域用于和其他 thread 的栈空间进行隔离。而栈内存空间一旦创建和初始化完成之后其大小就不能再有变化,这决定了在某些特殊场景下系统线程栈还是有溢出的风险。
|
|||
|
|
|||
|
### 创建和销毁
|
|||
|
- 线程创建和销毀都会有巨大的消耗,是内核级的交互(trap)。进入内核所消耗的性能代价比较高,开销较大。
|
|||
|
- goroutine 是用户态线程,是由 go runtime 管理,创建和销毁的消耗非常小。
|
|||
|
|
|||
|
### 调度切换
|
|||
|
- 抛开陷入内核,线程切换会消耗 1000-1500 纳秒(上下文保存成本高,较多寄存器,公平性,复杂时间计算统计),一个纳秒平均可以执行 12-18 条指令。所以由于线程切换,执行指令的条数会减少 12000-18000。
|
|||
|
- goroutine 的切换约为 200 ns(用户态、3个寄存器),相当于 2400-3600 条指令。因此,goroutines 切换成本比 threads 要小得多
|
|||
|
|
|||
|
### 复杂性
|
|||
|
- 线程的创建和退出复杂,多个thread间通讯复杂(share memory)
|
|||
|
- 不能大量创建线程,成本高,使用网络多路复用,存在大量callback。对于应用服务线程门槛高,例如需要做第三方库隔离,需要考虑引入线程池等
|