Golang 垃圾回收
1、标记清除算法
Golang 使用标记清除算法作为垃圾回收器的一部分。标记清除算法是一种常见的垃圾回收算法,它通过标记和清除未被引用的对象来回收内存空间。
Golang 中,垃圾回收器会定期扫描堆空间,并找出哪些对象没有被引用。如果一个对象没有被引用,那么它就是垃圾,垃圾回收器会将其回收并释放相应的内存空间。
1.1 标记清除算法阶段
标记清除算法主要分为两个阶段:标记阶段和清除阶段
标记阶段,垃圾回收器会遍历堆中的所有对象,并标记每个对象是否被引用。这个过程是通过将对象的标记位设置为 1 来完成的。如果一个对象没有被标记,则说明它没有被引用,需要被回收。
清除阶段,垃圾回收器会清除所有未被标记的对象,并释放相应的内存空间。
1.2 标记清除算法步骤
在 Golang 中,标记清除算法的具体实现包括以下步骤:
垃圾回收器会从根对象开始遍历整个对象树,并标记每个对象是否被引用。
所有被标记的对象会被复制到新的堆空间中,未被标记的对象则会被回收。
清除阶段会扫描整个堆空间,并释放未被标记的对象所占用的内存空间。
释放完成后,垃圾回收器会将新的堆空间与旧的堆空间交换,使新的堆空间成为当前的堆空间。
需要注意的是,标记清除算法可能会导致内存碎片化问题。因为被回收的对象并不一定是连续的,所以空闲的内存空间可能会被切割成多个小块。为了解决这个问题,Golang 采用了复制算法和标记整理算法。
2、标记复制算法
复制算法是将堆空间分为两个相等的区域,每次只使用其中一个区域,当这个区域用尽时,将存活的对象复制到另一个区域中,并释放原来的空间。这个过程会使得内存空间连续,但需要额外的空间用于复制对象。
3、标记整理算法
标记整理算法则是在标记和清除阶段之后,将所有存活的对象移动到堆空间的一端,而未被引用的对象则会被移动到堆空间的另一端。这个过程会使得空闲的内存空间变得连续。