执行一个full GC, 例如 GC.Collect(2),其实就是一个在不同 Generation标识和清扫的过程。具体大概的步骤如下:
- 首先给所有在LOH(Large object heap) 上的对象打上标识. 然后检查每个被标识的对象是否有其他对象引用. 如果对象被引用, 该对象将被取消标识, 对于没有引用的对象将准备被清除.
- LOH被清扫。所有被标识的对象从内存中被释放.
- 对象在 Gen2 被标识和引用检查.
- Gen2 被清扫.
- Gen2被压缩. (因为managed heap 会被压缩,所以不会像unmanaged heap 一样有内存fragmentation. 当然 pinned 的对象不会被移动)
- 对象在 Gen1 被标识和引用检查.
- Gen1被清扫.
- Gen1被压缩.
- Gen2结束位置的指针被更新. 所有原先在Gen1中没有被释放的对象现在在Gen2.
- 对象在Gen0被标识和引用检查.
- Gen0被清扫.
- Gen0被压缩.
- Gen1结束位置的指针被更新. 所有原先在Gen0中没有被释放的对象现在在Gen1.
需要注意的是LOH从来都不被压缩,所以不正确的使用LOH会产生内存fragmentation.
BitsBlue
浙公网安备 33010602011771号