江西南昌网站建设哪家公司好,打开百度网站首页,都江堰做网站,那些免费网站可以做国外贸易内存垃圾的产生
程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C等早期编程语言栈上的内存回由编译器负责管理回收#xff0c;而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收#xff0c;而堆上的内存由编译器…内存垃圾的产生
程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C等早期编程语言栈上的内存回由编译器负责管理回收而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收而堆上的内存由编译器和垃圾收集器负责管理回收给编程人员带来了极大的便利性。 垃圾是指程序向堆栈申请的内存空间随着程序的运行已经不再使用这些内存空间这时如果不释放它们就会造成垃圾也就是内存泄漏。 package main//假设每个人都拥有自己都一部手机type Person struct {phone *Phone}type Phone struct {money int}func main() {//定义一个Person为超超chao : new(Person)//超超一开始用的是iphone12iphone : Phone{money: 6599}chao.phone iphone//华为推出了鸿蒙于是超超果断入了一部mate40huawei : Phone{money: 5899}chao.phone huawei}
随着超超将手机从iphone换成了华为phone指向的内存空间就变成了垃圾这时就需要对phone指向的内存空间进行回收否则就变成了内存泄漏。 Golang垃圾回收机制
Go1.3采用的标记清除法Go1.5采用三色标记法Go1.8采用三色标记法混合写屏障。 标记清除法
分为两个阶段标记和清除
标记阶段从根对象出发寻找并标记所有存活的对象。
清除阶段遍历堆中的对象回收未标记的对象并加入空闲链表
缺点需要暂停程序STW
步骤
进行STW暂停程序业务逻辑然后从main函数开始找到不可达的内存占用和可达的内存占用开始标记程序找出可达内存占用并标记标记结束清除未标记的内存占用结束STW停止暂停让程序继续执行循环该过程直到main生命周期结束。 一开始的做法是将垃圾清理结束时才停止STW,后来优化了方案将清理垃圾放到了STW之后与程序运行同时进行这样做减少了STW的时长。但是STW会暂停用户逻辑对程序的性能影响是非常大的这种粒度的STW对于性能较高的程序还是无法接受因此Go1.5采用了三色标记法优化了STW。 三色标记法
将对象标记为白色灰色和黑色
白色不确定对象(默认色) 黑色存活对象灰色存活对象子对象待处理
步骤
将所有对象标记为白色从根节点集合出发将第一次遍历到的节点标记为灰色放入到集合列表中遍历灰色集合将灰色节点遍历到的白色节点标记为灰色并把灰色节点标记为黑色、循环整个过程直到灰色节点集合为空回收所有白色节点 这种方法有个缺陷如果对象的引用被用户修改了那么之前的标记就无效了。 分析bug的根源所在主要是因为程序在运行过程中出现了下面俩种情况
一个白色对象被黑色对象引用灰色对象与它之间的可达关系的白色对象遭到破坏
因此在此基础上拓展出了俩种方法强三色不变式和弱三色不变式
强三色不变式不允许黑色对象引用白色对象弱三色不变式黑色对象可以引用白色白色对象存在其他灰色对象对他的引用或者他的链路上存在灰色对象
为了实现这俩种不变式的设计思想从而引出了屏障机制即在程序的执行过程中加一个判断机制满足判断机制则执行回调函数。 屏障机制分为插入屏障和删除屏障插入屏障实现的是强三色不变式删除屏障则实现了弱三色不变式。值得注意的是为了保证栈的运行效率屏障只对堆上的内存对象启用栈上的内存会在GC结束后启用STW重新扫描。
插入屏障对象被引用时触发的机制当白色对象被黑色对象引用时白色对象被标记为灰色栈上对象无插入屏障 缺点在于如果对象1在栈上新创建了一个对象6由于栈没有屏障机制所以对象6仍为白色节点会被回收 所以栈在GC迭代结束时没有灰色节点会对栈执行STW重新进行扫描清除白色节点。STW时间为10-100ms
删除屏障对象被删除时触发的机制。如果灰色对象引用的白色对象被删除时那么白色对象会被标记为灰色。 缺点这种做法回收精度较低一个对象即使被删除仍可以活过这一轮再下一轮被回收。如果对象4没有引用对象3此时对象3应该作为垃圾被回收但是对象3却要等到下一轮GC才会被回收 同样也存在对栈的二次扫描影响程序的效率。 三色标记混合写屏障技术
基于插入写屏障和删除写屏障在结束时需要STW来重新扫描栈所带来的性能瓶颈Go在1.8引入了混合写屏障的方式实现了弱三色不变式的设计方式混合写屏障分下面四步
GC开始时将栈上可达对象全部标记为黑色不需要二次扫描无需STWGC期间任何栈上创建的新对象均为黑色被删除引用的对象标记为灰色被添加引用的对象标记为灰色