golang runtime是go语言运行所需要的基础设置。
java 、python中也有runtime,但是java、python中的runtime是虚拟机,而go的runtime和用户代码一起编译到一个可执行文件中。
go runtime大致可分成三部分:go调度,go内存管理,go GC。
1、简介一下go调度
先介绍一下go routine与go 调度的区别
我们都知道Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine。goroutine就是Go语言提供的一种用户态线程,当然这种用户态线程是跑在内核级线程之上的。当我们创建了很多的goroutine,并且它们都是跑在同一个内核线程之上的时候,就需要一个调度器来维护这些goroutine,确保所有的goroutine都使用cpu,并且是尽可能公平的使用cpu资源。
Go的调度器使用了三种结构:M,P,S
M代表内核线程,类似于标准的POSIX线程,M代表machine。G代表goroutine,它拥有自己的栈,程序计数器(instruction counter)和一些关于goroutine调度的信息(如正在阻塞的channel)。P代表processor,表示调度的上下文。可以把它看作是一个局部的调度器,让Go代码跑在一个单独的线程上。这是让Go从一个N:1调度器映射到一个M:N调度器的关键。2、简介一下go内存管理
Go 的内存管理基本上参考 tcmalloc
来实现的,只是细节上根据自身的需要做了一些小的优化调整。
Go 的内存是自动管理的,我们可以随意定义变量直接使用,不需要考虑变量背后的内存申请和释放的问题。
介绍一个很好的文章
图解tcmalloc整个的结构
图解tcmalloc
里面介绍了tcmalloc的几个结构,不同结构之间的联系
看完tcmalloc就差不多懂了
插一嘴我发现内核的slab机制跟这个也很像…
3、go GC
垃圾回收(Garbage Collection,简称GC)是编程语言中提供的内存管理功能
在传统的编程语言(主要指C/C++)中,程序员定义了一个变量,就是在内存中开辟了一段相应的空间来存值。由于内存是有限的,所以当程序不再需要使用某个变量的时候,就需要销毁该对象并释放其所占用的内存资源,好重新利用这段空间。在C/C++中,释放无用变量内存空间的事情需要由程序员自己来处理。当软件系统比较复杂,变量多的时候程序员往往就忘记或者在不该释放的时候释放内存了。这对于程序开发人员是一个比较头痛的问题。
为了解决这个问题,后来开发出来的几乎所有新语言(java,python,php等等)都引入了语言层面的自动内存管理 – 也就是语言的使用者只用关注内存的申请而不必关心内存的释放,内存释放由虚拟机(virtual machine)或运行时(runtime)来自动进行管理。而这种对不再使用的内存资源进行自动回收的功能就被称为垃圾回收。
go GC主要是用了三色标记法
在版本更新中具体的版本也在发生一些变化
整体难度还是比较大的。
推荐一篇帖子
深入理解Go的GC回收机制
当然还有一些其他的功能,如支持pprof、trace、race等等。还要重点说一下channel
channel是Go语言在语言级别提供的goroutine间的通信方式。我们可以使用channel在两个或 多个goroutine之间传递消息。
channel 会某种情况下出现阻塞,通过控制channel的阻塞来管理协程的并发与流程控制。
然后还有runtime的几个包
Gosched:让当前线程让出cpu
以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行NumCPU:返回当前系统的 CPU
核数量GOMAXPROCS:设置最大的可同时使用的 CPU
核数Goexit:退出当前 goroutine
(但是defer
语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标 *** 作系统
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)