MST

星途 面试题库

面试题:Go中Goroutine与线程在资源占用方面的区别

请阐述Go语言里Goroutine与传统线程在资源占用上有哪些显著的不同点,并说明为什么Goroutine在这方面具有优势。
30.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

资源占用不同点

  1. 内存占用
    • 传统线程:每个线程栈的初始大小通常相对较大,比如在许多操作系统上,默认线程栈大小可能是几MB(例如2MB)。这意味着创建大量线程时,内存占用会迅速增长,很容易耗尽系统内存。
    • Goroutine:Goroutine的栈初始大小非常小,一般只有2KB左右。并且其栈空间是可以根据需要动态增长和收缩的。这使得在创建大量Goroutine时,内存占用相对较少。
  2. 创建开销
    • 传统线程:创建线程的开销较大,因为操作系统需要为每个线程分配内核资源,如独立的内核栈、线程控制块(TCB)等。这些操作涉及到系统调用,会带来较高的上下文切换成本。
    • Goroutine:创建Goroutine的开销极小,它是由Go运行时(runtime)在用户态进行管理的。Go运行时通过自己的调度器(GPM模型:Goroutine、Processor、Machine)来管理Goroutine,创建一个Goroutine只需要在用户态分配少量内存用于栈和一些控制信息。

Goroutine优势原因

  1. 高效利用内存:由于Goroutine栈的初始大小小且可动态伸缩,在处理大量并发任务时,能有效避免因大量内存占用导致的系统资源耗尽问题。例如在一个高并发的网络服务器应用中,如果使用传统线程,可能在处理几千个并发连接时就因为内存不足而崩溃;而使用Goroutine,可轻松处理数万个甚至更多的并发连接。
  2. 高并发性能:极小的创建开销使得可以快速创建大量Goroutine,适合高并发场景。同时,Go运行时的调度器采用M:N调度模型(多个Goroutine映射到多个操作系统线程上),能更灵活地调度Goroutine,减少上下文切换开销。相比之下,传统线程的上下文切换开销大,在高并发时性能会显著下降。