1.CG机制与优化 1.1 什么时候需要垃圾回收? 1.1.1 提高了软件开发的抽象度; 1.1.2 程序员可以将精力集中在实际的问题上而不用分心来管理内存的问题; 1.1.3 可以使模块的接口更加的清晰,减小模块间的偶合; 1.1.4 大大减少了内存人为管理不当所带来的Bug; 1.1.5 使内存管理更加高效; 1.1.6 总的说来就是GC可以使程序员可以从复杂的内存问题中摆脱出来,从而提高了软件开发的速度、质量和安全性; 1.2 什么样的对象需要垃圾回收? 1.2.1 托管资源:指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,例如程序中分配的对象,作用域内的变量等,大部分对象都是托管资源; 1.2.2 存在堆里(含值类型+引用类型) 1.2.3(非托管资源)=>CLR不能控制或者管理的部分,这些资源有很多,比如文件流,数据库的连接,系统的窗口句柄,打印机资源,需要调用Dispose方法; 1.3为什么GC时,timeer没有被回收? 1.4 堆资源是怎么分配的? 1.4.1 空间有限 1.4.2 连续摆放 1.4.3 更新指针 1.4.4 局部化(locality) 1.4 Mark-Compact 标记压缩算法 1.4.1 Mark-Sweep 标记清除阶段,先假设heap中所有对象都可以回收,然后找出不能回收的对象,给这些对象打上标记,最后heap中没有打标记的对象都是可以被回收的; 1.4.2 Compact 压缩阶段,对象回收之后heap内存空间变得不连续,在heap中移动这些对象,使他们重新从heap基地址开始连续排列,类似于磁盘空间的碎片整理; 1.5 分代策略 1.5.1 1.5.2 第1次,遍历全部对象,找出没有引用的,删除,剩下1代; 1.5.3 第2次,遍历0代对象,找出没有引用的,删除,剩下升级1代 如果还不够空间,才会遍历1代,没有引用的删除,还在被使用的,升级为2代。都不够才会检查2代; 1.6 各代空间大小? 1.6.1 实际上是没有具体值的,由CLR管理。初始化时就会给出0代/1代的预算,然后动态调节!GC后,对象几乎没有留存,那么就会减小预算,加快回收频率,每次速度快; 1.6.2 如果GC后有很多对象留存,那么就会增加预算,降低回收频率,每次回收内容多; 1.6.3 如果空间不够,就会全面回收,再不够就OutOfMemory了; 1.7 回收假设? 1.7.1 对象越新,生存期越短; 1.7.2 对象越老,生存期越长; 1.7.3 回收部分资源,快过全部回收 1.8 什么时候GC? 1.8.1 new对象时–临界点; 1.8.2 Windows报告内存不够; 1.8.3 GC.Collect 强制GC; 1.8.4 程序退出或者卸载AppDomain; 1.9 怎么用GC. Collect? 1.9.1 大多数情况下,应该让GC自己决定回收时间,以更好的控制各代预算,也避免GC降低响应 1.9.2 如果知道大量对象无效,可以手动GC,尤其是2代; 1.9.3 大对象策略 1.9.3.1 85000字节为限 1.9.3.2 独立的地址空间 1.9.3.3 不会移动压缩大对象,成本高,但也造成了碎片 1.9.3.4 总是2代对象 1.10 垃圾回收模式 1.10.1 工作站=>单线程回收; 1.10.2 服务器=>多区域并行回收; 1.10.3<configruration><runtime><gcServer enabled="true"></runtime></configruration>