Go(lang)的地址空间是多少?

Tim*_*nov 6 memory parallel-processing concurrency memory-management go

我尝试了解Go中并发编程的基础知识.几乎所有文章都使用术语"地址空间",例如:"所有goroutines共享相同的地址空间".这是什么意思?

我试图从wiki中理解以下主题,但它没有成功:

但是目前我很难理解,因为我在内存管理和并发编程等方面的知识非常差.有许多未知的单词,如段,页面,相对/绝对地址,VAS等.

有人可以向我解释问题的基础吗?可能有一些有用的文章,我找不到.

Von*_*onC 14

Golang规范:

A" go"语句开头的函数调用的执行作为独立的控制并发线程,或者goroutine,在同一范围内的地址空间.

有人可以向我解释问题的基础吗?

"地址空间"是一个通用术语,可以适用于许多情况:

通过组合足够唯一标识的限定符来创建地址空间,以使地址明确(在特定地址空间内)

Dave Cheney的演讲" 让快速前进的五件事 "说明了在相同的进程地址空间中使用goroutine解决的主要问题:堆栈管理.

戴夫的资格是"地址空间",首先讲的是:

由于进程切换可以在进程执行的任何时刻发生,操作系统需要存储所有这些寄存器的内容,因为它不知道当前正在使用哪些寄存器.

这导致了线程的开发,这些线程在概念上与进程相同,但共享相同的内存空间.

(所以这是关于记忆的)

然后Dave说明了进程地址空间中的堆栈(进程管理的地址):

http://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-39.jpg

传统上在进程的地址空间内,

  • 堆位于内存的底部,位于程序(文本)的上方并向上增长.
  • 堆栈位于虚拟地址空间的顶部,并向下增长.

另请参阅" 堆栈和堆的内容和位置? ".

问题:

因为堆和堆栈相互覆盖将是灾难性的,操作系统通常会安排在堆栈和堆之间放置一个不可写内存区域,以确保如果它们确实发生冲突,程序将中止.

使用线程,可能会限制进程的堆大小:

http://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-41.jpg

随着程序中线程数的增加,可用地址空间的数量也会减少.

goroutine使用不同的方法,同时仍然共享相同的进程地址空间:

那些goroutines的堆栈要求怎么样?

Go编译器不是使用保护页,而是在每个函数调用的一部分插入一个检查,以检查是否有足够的堆栈来运行该函数.如果没有,运行时可以分配更多的堆栈空间.

由于这种检查,goroutines初始堆栈可以做得更小,这反过来允许Go程序员将goroutines视为廉价资源.

Go 1.3引入了一种管理这些堆栈的新方法:

http://dave.cheney.net/wp-content/uploads/2014/06/Gocon-2014-45.jpg

如果goroutine的堆栈太小,则不会添加和删除其他堆栈段,而是分配新的更大的堆栈.

旧堆栈的内容被复制到新堆栈,然后goroutine继续其新的更大的堆栈.

在第一次调用H之后,堆栈将足够大,以便检查可用堆栈空间将始终成功.