For-learning-Go-Tutorial
在理解垃圾回收之前,我们先理解一下Cache 和 Buffer,这两个都是缓存,这两者之间有什么区别呢?
buffer:缓冲
用于存储速度不同步的设备或优先级不同的设备之间传输数据;通过buffer可以减少进程间通信需要等待的时间,当存储速度快的设备与存储速度慢的设备进行通信时,存储慢的数据先把数据存放到buffer,达到一定程度存储快的设备再读取buffer的数据,在此期间存储快的设备CPU可以做其他的事情。
A buffer is something that has yet to be "written" to disk.
cache:缓存
是高速缓存,是位于CPU和主内存之间的容量较小但速度很快的存储器,因为CPU的速度远远高于主内存的速度,CPU从内存中读取数据需等待很长的时间,而 Cache保存着CPU刚用过的数据或循环使用的部分数据,这时从Cache中读取数据会更快,减少了CPU等待的时间,提高了系统的性能。
A cache is something that has been "read" from the disk and stored for later use.
buffer是用于存放将要输出到disk(块设备)的数据,进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 I/O,以减少响应次数,而cache是存放从disk上读出的数据,为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到加快访问速度的作用。。二者都是为提高IO性能而设计的。
而Go标准库Buffer是一个可变大小的字节缓冲区,可以用Wirte和Read方法操作它.
Golang 垃圾回收发展史
通常在编程中的垃圾指内存中不再使用的内存区域,自动发现与释放这种内存区域的过程就是垃圾回收。
内存资源是有限的,而垃圾回收可以让内存重复使用,并且减轻开发者对内存管理的负担,减少程序中的内存问题。
我们透过这个来看下Go垃圾回收发展史:
go1.1,提高效率和垃圾回收精确度。
go1.3,提高了垃圾回收的精确度。
go1.4,之前版本的runtime大部分是使用C写的,这个版本大量使用Go进行了重写,让GC有了扫描stack的能力,进一步提高了垃圾回收的精确度。
go1.5,目标是降低GC延迟,采用了并发标记和并发清除,三色标记,write barrier,以及实现了更好的回收器调度,设计文档1,文档2,以及这个版本的[Go talk]。
go1.6,小优化,当程序使用大量内存时,GC暂停时间有所降低。
go1.7,小优化,当程序有大量空闲goroutine,stack大小波动比较大时,GC暂停时间有显著降低。
go1.8,write barrier切换到hybrid write barrier,以消除STW中的re-scan,把STW的最差情况降低到50us,设计文档。
混合屏障的优势在于它允许堆栈扫描永久地使堆栈变黑(没有STW并且没有写入堆栈的障碍),这完全消除了堆栈重新扫描的需要,从而消除了对堆栈屏障的需求。重新扫描列表。特别是堆栈障碍在整个运行时引入了显着的复杂性,并且干扰了来自外部工具(如GDB和基于内核的分析器)的堆栈遍历。
此外,与Dijkstra风格的写屏障一样,混合屏障不需要读屏障,因此指针读取是常规的内存读取; 它确保了进步,因为物体单调地从白色到灰色再到黑色。
混合屏障的缺点很小。它可能会导致更多的浮动垃圾,因为它会在标记阶段的任何时刻保留从根(堆栈除外)可到达的所有内容。然而,在实践中,当前的Dijkstra障碍可能几乎保留不变。混合屏障还禁止某些优化:特别是,如果Go编译器可以静态地显示指针是nil,则Go编译器当前省略写屏障,但是在这种情况下混合屏障需要写屏障。这可能会略微增加二进制大小。
- go1.9,提升指标主要是:
过去
runtime.GC
,debug.SetGCPercent
, 和debug.FreeOSMemory
都不能触发并发GC,他们触发的GC都是阻塞的,go1.9可以了,变成了在垃圾回收之前只阻塞调用GC的goroutine。debug.SetGCPercent
只在有必要的情况下才会触发GC。
go.1.10,小优化,加速了GC,程序应当运行更快一点点。
go1.12,显著提高了堆内存存在大碎片情况下的sweeping性能,能够降低GC后立即分配内存的延迟。