下面两篇文章对C#GC原理做了比较详细的分析
GC只能回收托管对象,对于未托管对象无法管理。
比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法。
在CLR中,对于小对象堆SOH,采用的回收算法为标记-缩并算法 ,由于移动大对象比较耗费时间,所以在LOH上,CLR采用了标记-清除算法 ,即只做对象的清除并不对大对象堆进行压缩。
一.标记压缩算法
标记清除(找出不能回收的对象,打上标记)------->压缩阶段(对象回收之后内存不连续,移动对象)--------->指针修复
搜索roots:全局对象、静态变量、局部对象、函数调用参数、当前CPU寄存器中的对象指针(还有finalization queue)等。主要可以归为2种类型:已经初始化了的静态变量、线程仍在使用的对象(stack+CPU register)
Reachable objects:指根据对象引用关系,从roots出发可以到达的对象。
二、 Generational 分代算法
将对象按照生命周期分成新的、老的,根据统计分布规律所反映的结果,可以对新、老区域采用不同的回收策略和算法,加强对新区域的回收处理力度,争取在较短时间间隔、较小的内存区域内,以较低成本将执行路径上大量新近抛弃不再使用的局部对象及时回收掉
cpu cache
1、为毛最好不要使用string 做频繁的累加?要使用stringbulder
编译器会在每一次累加创建一个string(编译器优化不够智能),stringBuilder为可变字符型,不需要每次都去分配内存