← 返回目录

goroutine什么情况会发生内存泄漏?如何避免。

第 16 / 29 卷日期:

goroutine什么情况会发生内存泄漏?如何避免。

在Go中内存泄露分为暂时性内存泄露和永久性内存泄露。

暂时性内存泄露

获取长字符串中的一段导致长字符串未释放获取长slice中的一段导致长slice未释放

在长slice新建slice导致泄漏

string相比切片少了一个容量的cap字段,可以把string当成一个只读的切片类型。获取长string或者切片中的一段内容,由于新生成的对象和老的string或者切片共用一个内存空间,会导致老的string和切片资源暂时得不到释放,

造成短暂的内存泄漏

go的垃圾回收机制了解吗?

Go垃圾回收

Go1.3之前采用标记清除法, Go1.3之后采用三色标记法,Go1.8采用三色标记法+混合写屏障。

  1. 标记清除法

初始版本的Go语言使用了一个基于标记-清扫(Mark-Sweep)算法的垃圾回收器。

在标记清除算法中,首先从根对象(如全局变量、栈中的引用等)出发,标记所有可达对象。这一过程通常使用深度优先搜索或广度优先搜索进行。标记的方式通常是将对象的标记位从未标记改为已标记。所有的可达对

象都被标记为“活动”或“存活”。

在清扫阶段,遍历整个堆内存,将未被标记的对象视为垃圾,即不再被引用。所有未被标记的对象都将被回收,它们的内存将被释放,以便后续的内存分配。

标记清除算法执行完清扫阶段后,可能会产生内存碎片,即一些被回收的内存空间可能是不连续的。为了解决这个问题,一些实现中可能会进行内存碎片整理。

标记清除算法的主要优势是能够回收不再使用的内存,但它也有一些缺点。其中一个主要的缺点是清扫阶段可能会引起一定程度的停顿,因为在这个阶段需要遍历整个堆内存。另外,由于标记清除算法只关注“存活”和

“垃圾”两种状态,不涉及内存分配的具体位置,可能导致内存碎片的产生。

  1. 三色标记法

三色标记:将对象分为三种颜色:白色、灰色、和黑色。初始时,所有对象都被标记为白色,表示它们都是未被访问的垃圾对象。

根搜索:垃圾回收从根对象开始搜索,根对象包括全局变量、栈上的对象以及其他一些持有对象引用的地方。

所有根对象被标记为灰色,表示它们是待处理的对象。

标记阶段:从灰色对象开始,垃圾回收器遍历对象的引用关系,将其引用的对象标记为灰色,然后将该对象标记为黑色。这个过程一直进行,直到所有可达对象都被标记为黑色。

并发标记:在标记阶段,垃圾回收器采用并发标记的方式,与程序的执行同时进行。这意味着程序的执行不会因为垃圾回收而停顿,从而减小了对程序性能的影响。

清扫阶段:在标记完成后,垃圾回收器会扫描堆中的所有对象,将未被标记的对象回收(释放其内存)。这些未被标记的对象被认为是不可达的垃圾。

内存返还:垃圾回收完成后,系统中的内存得以回收并用于新的对象分配。

GC触发:垃圾回收的触发条件通常是在分配新对象时,如果达到一定的内存分配阈值,就会触发垃圾回收。

另外,一些特定的事件(如系统调用、网络阻塞等)也可能触发垃圾回收。

全站分卷索引 · 29 卷
  1. 1代码随想录知识星球精华(最强八股文)第五版(Go篇))
  2. 2Go string 和 []byte 的区别
  3. 3数组和切片的区别
  4. 4扩容前后的Slice是一样的吗
  5. 5Go语言map是有序的还是无序的, 为什么
  6. 6go里面的map是并发安全的吗?如何并发安全
  7. 7Go 的错误处理和 Java 的异常处理对比
  8. 8介绍一下panic和recover
  9. 9什么是defer?有什么作用
  10. 10Go并发
  11. 11进程、线程的区别
  12. 12什么是go runtine
  13. 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
  14. 14什么是互斥锁(mutex)?在什么情况下会用到它们?
  15. 15Mutex有几种模式
  16. 16goroutine什么情况会发生内存泄漏?如何避免。
  17. 17Go语言中GC的流程是什么
  18. 18Go 中的内存逃逸现象是什么?
  19. 19CAP 理论,为什么不能同时满足
  20. 20说一下 Gin 的路由怎么实现的
  21. 21简述slice的底层原理,和数组的区别是什么
  22. 22defer底层原理
  23. 23侵入式和非侵入式的区别
  24. 24goroutine与线程的区别
  25. 25goroutine在什么情况下会被挂起呢?
  26. 26GC(垃圾回收)原理 1.5版本
  27. 27简述Go的垃圾回收机制
  28. 28协程优势及其通信方式
  29. 29Go的内存对齐