这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
详细知识点介绍
- 垃圾回收
- 堆空间的分配
- 代码静态分析
自动内存管理
自动内存管理的一些相关概念如下:
- Mutator:业务线程
- Collector: GC 线程
- Serial GC:只有一个 collector
- Parallel GC:支持多个 collector 同时运行的 GC 算法
- Concurrent GC: mutator 和 collector 可同时运行的 GC 算法
评价一个 GC 算法的好坏,主要在以下几点:
安全性(Safety):不能回收存活的对象
吞吐率(Throughput):
暂停时间(Pause Time):Stop The World(STW)
常见的垃圾回收思路有追踪垃圾回收和引用计数。追踪垃圾回收的步骤包括标记根对象->标记可达对象(求指针指向关系的传递闭包)->清理不可达对象;引用计数的中心思想是记录每个对象所关联的指针数目(指向该对象的指针数目),当其降为0时即可清理该对象(这让我想到了 Linux 中ls -l看到的链接数)。和追踪垃圾回收相比,引用计数有内存管理过程平摊、实现简单等优点,但也有开销大、清理不彻底(如环状引用)等缺点。
在追踪垃圾回收清理中,清理不可达对象的方式包括:
- 将存活对象复制到另外的内存中(Copying GC)
- 将死亡对象的内存标记为“可分配”(Mark-Sweep GC)
- 移动整理存活对象(Mark-Compact GC)
Go 的内存分配
Go 的 heap 空间的分配过程大致如下:
- 调用系统调用
mmap()向操作系统申请一块内存- 将这块内存分割为大块
- 将大块分为特定大小的小块
- 对于含有指针的对象,进行 scan mspan;反之进行 noscan mspan。
Go
静态分析
GoLang 代码编译的大致过程如下:
- 词法分析:生成词素(lexeme)
- 语法分析:生成语法树
- 语义分析:生成类型信息、语义检查
- 中间代码分析:生成与平台无关的 Intermediate Representation (IR)
- 代码优化:对 IR 进行与平台无关的优化
- 代码生成:生成目标代码
静态分析是指不执行代码,推导程序行为、分析程序性质。常见的静态分析包括控制流(Control flow)分析(分析程序执行流程)和数据流(Data flow)分析(数据在控制流上的传递)。静态分析有助于简化代码,提高程序运行效率。
内联(Inline)是指将被调用函数的函数体(callee)的副本替换到被调用的位置上,GoLang编译器默认对简短的函数进行了内联。对简短的函数进行内联可减少函数调用的开销,提高程序运行效率;但是函数内联会增大程序体积、降低 instruction cache 效率。
逃逸分析是指代码中指针的动态作用域。对于没有逃逸的对象(作用范围在函数内)可直接在 stack 为其分配内存,降低 GC 压力。
本文若有不足之处,欢迎纠正(≧^.^≦)喵~
我的其他笔记,可在掘金或 Github( github.com/DoudiNCer/IWnA )阅读