go 内存管理&性能优化 | 青训营笔记

66 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

一、本堂课内容:

这节课大部分是对各种概念的介绍和说明,并没有太深入讲解。

1. 自动内存管理

  • 自动内存管理:由程序语言的运行时系统管理动态内存
  • 避免手动内存管理,专注于实现业务逻辑
  • 保证内存使用的正确性安全性: double-free problem, use-after-free problem
  • 任务:为新对象分配空间;找到存活对象;回收死亡对象的内存空间

GC (garbage collector)

垃圾回收是计算机科学中一个重要的领域,它主要用于回收系统中不再使用的内存空间。在这篇文章中,我们将讨论几种常见的垃圾回收方法,包括并发 GC,并行 GC,追踪垃圾回收,引用计数和分代 GC。

并发 GC 是一种并行进行垃圾回收的方法。在这种方法中,垃圾回收器在主线程运行时并发地进行垃圾回收。这种方法可以减少垃圾回收对系统性能的影响,但是会增加系统的复杂性。

并行 GC 是一种在多个线程上并行进行垃圾回收的方法。在这种方法中,垃圾回收器会在多个线程上同时进行垃圾回收。这种方法可以提高垃圾回收的效率,但是会增加系统的复杂性。

追踪垃圾回收是一种基于标记-清除算法的垃圾回收方法。在这种方法中,垃圾回收器会通过标记未使用的对象并将其清除来回收内存。这种方法简单易实现,但会导致内存碎片问题。

引用计数是一种基于引用计数算法的垃圾回收方法。在这种方法中,垃圾回收器会为每个对象维护一个引用计数,当对象的引用计数为0时,说明该对象不再被使用,可以回收。这种方法简单易实现,但会有循环引用问题。

分代 GC 是一种基于分代算法的垃圾回收方法。在这种方法中,垃圾回收器会将内存分为不同的代,每个代都有不同的回收策略。新生代的对象会被频繁回收,而老年代的对象会被少量回收。这种方法可以提高垃圾回收的效率,并且可以减少内存碎片问题。

2. Go 内存管理及优化

TCMalloc 是 Google 开发的一种高效的内存分配器。它使用了线程缓存和局部性优化策略,能够在多核环境下提高内存分配的效率。Go 语言默认使用 TCMalloc 作为其内存分配器,因此开发者无需额外设置就能享受到TCMalloc的优秀性能。

scan object & noscan object。scan object是指需要在垃圾回收过程中扫描的对象,而noscan object则是指不需要扫描的对象。Go语言中的垃圾回收器会对scan object进行标记清除,而对于noscan object则会直接释放。因此,如果需要优化内存管理,可以尽量使用noscan object来减少垃圾回收的开销。

mspan、mcache 和 mentral。mspan是Go语言中的内存页管理器,它管理着内存中的每一页。mcache则是线程级别的内存缓存,它可以提高内存分配的效率。mentral是Go语言中的垃圾回收器,它负责管理整个程序的内存。通过对mspan、mcache和mentral的优化,可以提高Go语言程序的内存管理效率。

3. Go 编译器优化

Go编译器对代码的优化可以通过对函数内联和逃逸分析来实现的。

函数内联是指在编译时将函数调用替换为函数体代码,这样可以减少函数调用的开销,提高程序的执行效率。Go编译器会在编译时自动对符合条件的函数进行内联优化,可以通过设置编译器参数来控制内联的阈值。

逃逸分析是指在编译时对变量的生命周期进行分析,以确定变量是否可以在栈上分配。如果变量只在当前函数中使用,那么就可以在栈上分配,这样可以减少内存分配的开销。Go编译器会自动进行逃逸分析,并对符合条件的变量进行栈分配。

通过函数内联和逃逸分析,Go编译器可以在编译时对代码进行优化,提高程序的执行效率。这两种优化方式都是在编译时进行的,不需要额外的代码改动,可以自动对符合条件的代码进行优化。

需要注意的是,函数内联和逃逸分析并不是总能够提高程序性能。如果函数较大,内联后可能会增加代码体积,影响程序性能。如果变量在多个函数中使用,那么在栈上分配可能会增加函数间的数据传递开销。因此,需要根据具体情况来决定是否使用这些优化。

二、课后个人总结:

  1. 垃圾回收是一个重要的领域,不同的垃圾回收方法都有各自的优缺点。在选择垃圾回收方法时,要根据系统的需求和特点来选择最合适的方法,有的时候混合使用才能达到最优解。
  2. Go语言的内存管理和优化是非常重要的一部分。通过使用 TCMalloc、scan object和noscan object、mspan、mcache 和 mentral,可以提高Go语言程序的内存管理效率。开发者应该对这些技术有所了解,并在实际开发中运用它们来优化程序性能。
  3. Go编译器对代码的优化是一种非常有效的手段,可以提高程序性能和降低内存开销。但是需要根据具体情况来决定是否使用这些优化。即使是使用了优化,也不能忽略代码设计和性能测试等其他因素对程序性能的影响哦。

三、引用参考:

主要大纲是按这个来的: juejin.cn/post/718952…