.NET GC 精要(四)

49 篇文章 1 订阅

本文讲述了 .NET GC 的一些细节知识,内容大部分来自于书籍 Under the Hood of .NET Memory Management
(注:本文假设你了解 .NET 的基础知识,譬如值类型,引用类型等)

进阶

之前在讲述 GC 分代回收的时候,我们只是了解了一下 SOH(Small Object Heap) 相关的内存回收行为,实际上,在进行 Gen 2 GC(也称为 full GC)时, GC 流程同样会回收 LOH(Large Object Heap)的内存,只是在方式方法上, LOH 的内存回收和 SOH 的内存回收有很大不同.

首先, LOH 的内存分布比较"直白",并没有 SOH 中所谓的分代概念(Gen 0, Gen 1 和 Gen 2).

再者, 由于 LOH 存储的是大于等于 85000 字节的大对象,所以复制移动这些对象的成本很高,所以, LOH 也并不会进行内存压缩(SOH 对各个分代都会进行内存压缩).

在(大)对象的申请与释放(即 Gen 2 GC)过程中, LOH 会将各个可用的内存区域记录到一个被称为 Free Space Table 的表中:

![]

在申请(大)对象时, .NET 会首先检查 Free Space Table,如果发现有足够的可用内存,则会将(大)对象分配到对应的可用内存区域中,并更新 Free Space Table,如果找不到足够的可用内存, .NET 会将(大)对象分配到当前的堆尾 (有可能会申请新的内存).

![]

(图中 Object E 被分配到了堆尾,即 Object D 之上)

出于性能考虑, .NET 更偏向于将对象分配至堆尾(当然,这种偏向也会导致 LOH 出现更多的内存碎片)

另外值得一提的是, LOH 存储的对象其实也并不都大于等于 85000 字节,对于一些内部数组,譬如 double 数组,由于 1 个 double 占据 8 个字节,似乎 double 数组的长度要大于等于 10625(85000 / 8)(此处我们忽略 double 数组的一些额外存储消耗)才会存储于 LOH 中,但实际上,仍然是出于性能考虑,大于等于 1000 长度的 double 数组就会存储于 LOH 中(不同类型数组的相关阈值也有所不同).

未完待续(to be continued)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值