城乡住房建设部网站保证金,江门建设建筑网站,广告网络,中国机械加工制造网写在前面前文主要介绍了ObjectPool的一些理论基础#xff0c;本文主要从源码角度理解Microsoft.Extensions.ObjectPool是如何实现的。下图为其三大核心组件图#xff1a;核心组件ObjectPoolObjectPool是一个泛型抽象类#xff0c;里面只有两个抽象方法#xff0c;Get和Retu… 写在前面前文主要介绍了ObjectPool的一些理论基础本文主要从源码角度理解Microsoft.Extensions.ObjectPool是如何实现的。下图为其三大核心组件图核心组件ObjectPoolObjectPool是一个泛型抽象类里面只有两个抽象方法Get和Return。它从底层定义了最一般的接口。Get方法用于从对象池获取到可用对象如果对象不可用则创建对象并返回出来Return方法用户将对象返回到对象池源码如下ObjectPoolProviderObjectPoolProvider也是抽象类其内部内置了一个已经实现的Create泛型方法以及一个抽象Create方法这代表两种ObjectPool的创建方式一个是基于默认策略的一个是基于用户自定义策略的。IPooledObjectPolicy这个接口是一个泛型接口用于提供一种策略来管理对象池中的对象同样也有两个方法Create和Return。Create方法用于创建相关类型实例Return方法用于将已经使用好的对象放回到对象池的时候进行逻辑处理包括对象的状态重置以及是否能够放回到对象池该接口有一个实现PooledObjectPolicy这是一个抽象类内部有两个抽象方法实现机制其内部实现逻辑较为简单充分考虑到了一般实现、对象追踪、对象释放等场景的使用方式。以下为其逻辑图DefaultObjectPoolDefaultObjectPool实现了ObjectPool其内部维护了一个结构体类型的私有数组用于存储相关对象。该数组的大小在构造函数中定义其实际大小为输入值减去1默认情况下其值为逻辑处理器数量的两倍主要是因为DefaultObjectPool单独将首项定义了出来。以下为DefaultObjectPool中Get和Return的实现通过源码可以知道这两个方法大量使用了Interlocked.CompareExchange比较location1与comparand如果不相等什么都不做如果location1与comparand相等则用value替换location1的值。无论比较结果相等与否返回值都是location1中原有的值。Interlocked.CompareExchange的使用确保了线程安全性。DefaultObjectPoolProviderDefaultObjectPoolProvider实现了ObjectPoolProvider该类重写了Create方法并返回ObjectPool对象。该类还定义了MaximumRetained属性默认情况下其值为逻辑处理器数量的两倍。其源码如下比较简单其中DisposableObjectPool是DefaultObjectPool类的派生类这个类也实现了IDisposable用于创建可手动释放的ObjectPool对象。其相关代码如下DefaultPooledObjectPolicy该类继承了PooledObjectPolicy实现也非常简单。不过值得注意的是PooledObjectPolicy还有一个实现StringBuilderPooledObjectPolicy这个类从命名上看就知道是基于StringBuilder的。其内部默认定义了StringBuilder的大小以及初始化容量。并确定了超出容量后将不允许归还对象。在我们自定义PooledObjectPolicy的时候可以参考这段实现去扩展新的PooledObjectPolicy对象。我们看一下源码对象追踪该库内部定义了LeakTrackingObjectPool和LeakTrackingObjectPoolProvider用于追踪对象状态。LeakTrackingObjectPoolProvider会根据构造函数传入的ObjectPoolProvider类型对象创建LeakTrackingObjectPool实例。LeakTrackingObjectPool内部定义了ConditionalWeakTableT, Tracker类型的数组MSDN的解释是使编译器可以将对象字段动态附加到托管对象这个对象会自动维护内部的键值对而不会一直使其停留在内存中。Tracker是LeakTrackingObjectPool的内部类其目的是为了方便我们对对象本身进行维护跟踪其定义如下