刚刚骚情的跑了下NLog测试,,,,,一篇文章就那么Crash了~~~
好吧,这次简化下,直接进入正题,有关GC的东东参考网上大部分文章吧。
源码分析
// StringBuilder 的建立也会耗费大量的资源,因此共用他们,使用这个类来管理池子
//需要了从这里获取一个,用完自动释放 ItemHolder 即可释放会池子
// 例如 using (var itemHolder = pool.Acquire()){}
internal class StringBuilderPool{private StringBuilder _fastPool;private readonly StringBuilder[] _slowPool;private readonly int _maxBuilderCapacity;/// <summary>/// Constructor/// </summary>/// <param name="poolCapacity">Max number of items</param>/// <param name="initialBuilderCapacity">Initial StringBuilder Size</param>/// <param name="maxBuilderCapacity">Max StringBuilder Size</param>public StringBuilderPool(int poolCapacity, int initialBuilderCapacity = 1024, int maxBuilderCapacity = 512 * 1024){//一个快速池子,一直保持_fastPool = new StringBuilder(10 * initialBuilderCapacity);// 一个慢速池子,如果快速池子被占用,则从慢速池子取一个_slowPool = new StringBuilder[poolCapacity];for (int i = 0; i < _slowPool.Length; ++i){_slowPool[i] = new StringBuilder(initialBuilderCapacity);}_maxBuilderCapacity = maxBuilderCapacity;}/// <summary>/// Takes StringBuilder from pool/// </summary>/// <returns>Allow return to pool</returns>public ItemHolder Acquire(){//1.come on baby,先尝试分配快速池子StringBuilder item = _fastPool;//2.如果你幸运的拿到快速池子,则尽快把快速池子置空,不要让别人抢到了,否则,你就必须进慢速池子取了if (item == null || item != Interlocked.CompareExchange(ref _fastPool, null, item)){//3.你好,兄弟,你已经进入慢车道,来,一个个给你试试能用不for (int i = 0; i < _slowPool.Length; i++){item = _slowPool[i];if (item != null && item == Interlocked.CompareExchange(ref _slowPool[i], null, item)){//4.啊哈,发现一个慢速的,来,给你,别嫌弃return new ItemHolder(item, this, i);}}//这么倒霉,一个都没有,算了,再给你分配一个新的吧,记住,你的编号~~~咦, 第0个吧~~~return new ItemHolder(new StringBuilder(), null, 0);}else{//你是幸运之星,快速跑~~~~return new ItemHolder(item, this, -1);}}/// <summary>/// Releases StringBuilder back to pool at its right place/// </summary>private void Release(StringBuilder stringBuilder, int poolIndex){//来,兄弟,好借好还,再借不难//什么,这么大,我记得借你时没这么大啊,让我再检查检查if (stringBuilder.Length > _maxBuilderCapacity){//我靠,你是快车道的,那就给你10倍大小如何,这都超了,那对不起,减半了~~// Avoid high memory usage by not keeping huge StringBuilders alive (Except one StringBuilder)int maxBuilderCapacity = poolIndex == -1 ? _maxBuilderCapacity * 10 : _maxBuilderCapacity;if (stringBuilder.Length > maxBuilderCapacity){stringBuilder = new StringBuilder(maxBuilderCapacity / 2);}}stringBuilder.Length = 0;//好,各就各位...if (poolIndex == -1){_fastPool = stringBuilder;}else{_slowPool[poolIndex] = stringBuilder;}}//下面是个池化对象类/// <summary>/// Keeps track of acquired pool item/// </summary>public struct ItemHolder : IDisposable{public readonly StringBuilder Item;readonly StringBuilderPool _owner;readonly int _poolIndex;public ItemHolder(StringBuilder stringBuilder, StringBuilderPool owner, int poolIndex){Item = stringBuilder;_owner = owner;_poolIndex = poolIndex;}/// <summary>/// Releases pool item back into pool/// </summary>public void Dispose(){if (_owner != null){_owner.Release(Item, _poolIndex);}}}}