.Net CLR 内存模型小结

.Net CLR的内存模型和JVM的内存模型有很多相似的地方。《JVM 结构小结》

 

 1 进程内存空间

应用程序的内存受进程的虚拟地址空间的限制。

  • 32位进程:最多1.5GB
  • 64位进程:最多8TB

 

2 引用跟踪算法

为了解决“引用计数算法”中处理不好循环引用的问题,CLR采用了引用跟踪算法,只关心引用类型的变量——根。值类型变量直接包含实例,变量销毁,整个实例也销毁了。

 

3 GC过程

3.1 暂停线程

暂停进程中所有线程,防止它们在GC期间更改对象状态。

 

3.2 标记阶段

  1. 遍历堆中所有对象,并将同步块索引字段中的一位设为0。即假定所有对象都不可达,都是垃圾。
  2. 遍历所有(栈中的)活动根,将其引用对象的同步块索引中的位设为1,表示可达,需要保留。
  3. 检查上一步可达对象中的根,标记其引用的对象为可达。对可达对象重复执行该步骤,直到所有根都检查完毕。



 

 

3.3 压缩阶段

将需要保留的对象移到一起。更新每个根中引用对象的地址(即减去对象在内存中偏移的字节数)。

 

4 代

类似JVM内存管理中的新生代和老年代概念,.Net CLR的中也有“代”的概念。

  • CLR在分配新对象时,如果所需内存超出预算,马上执行一次GC。
  • 为了加快速度,只回收 0代 对象,忽略 1代 中的不可达对象。幸存下的 0代 对象提升为 1代。
  • 如果发现 1代 的内存占比过高,会回收 0代 和 1代 中所有不可达对象。幸存的 1代 升为 2代(最高代),0代 升为 1代。
  • 如果没有回收到足够内存,CLR会做一次完整GC。如果还是不够,就抛异常 OutOfMemoryException。
  • CLR会在GC过程中了解应用程序的行为,从而动态调节各代对象内存占比的预算。

 

5 大对象

(目前)85000字节及以上的对象被认为大对象。因为在内存中移动它的代价太高,GC一般不压缩大对象。大对象被归为 2代对象。常见的有大字符串和I/O字节数组等。

 

6 GC模式

6.1 工作站模式

为避免用户感到焦虑,GC被优化成低延时。

 

6.2 服务器模式

为提升吞吐量和资源利用率,(假定)机器的所有CPU都可用于辅助GC。托管堆被拆分为“一个CPU,一块内存区域”,每个CPU上都运行一个特殊线程,它们并发回收各自区域。

可通过配置文件启用服务器模式。

<configuration>
  <runtime>
    <gcServer enabled="true" />
  </runtime>
</configuration>

 

 

7 手动监视和控制对象的生存期

每个AppDomain一个GC句柄表,表中每一项包含堆中一个对象的引用和如何监控对象的标志(flag)。

为简化操作,用WeakReference<T>来替代GCHandle。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值