从Glide源码里面学习到的对象池知识
对象池的概念是我在Glide源码里面第一次接触到的。它的作用是回收那些被释放的对象资源然后达到重用的目的。为什么要重用被释放的对象资源呢?因为创建对象是一个需要消耗内存的事情,重复大量的这些操作,会造成内存的抖动,这一点是每个开发者不愿意看到的。
来看源码:
先看Engine
类的waitForExistingOrStartNewJob
方法,这个方法里面有一个创建对象DecodeJob
的操作。它就用到了对象池的概念。
1 | // Engine |
来直接看decodeJobFactory.build
方法:
1 | // Engine.DecodeJobFactory |
好重点来了:pool对象。从名字就能知道这是一个池子,是什么池子?当然是对象池子。
1 | final Pools.Pool<EngineJob<?>> pool = |
看下FactoryPools
代码:
1 | // FactoryPools |
这里就是它设计精妙的地方,创建对象的操作用一个接口回调出来:
1 | public interface Factory<T> { |
现在知道了pool
对象的由来,它就是FactoryPool
。
继续回到代码pool.acquire()
,看FactoryPool
的acquire
:
1 | // FactoryPools |
可以看到在acquire
里面有调用了一个pool
:这个pool
其实是SynchronizedPool
,在创建FactoryPools
的时候创建的。这里为啥会出现两个Pool。这个FactoryPools
是从池子里做取创建得操作。SynchronizedPool
这个池子做的是存删得操作。
1 | //SynchronizedPool |
总结:
它的逻辑就是,我想获取对象的时候。FactoryPools
执行acquire
方法,然后这个方法调用SynchronizedPool
里面的acquire
方法从HashMap
里面取。如果没取到对象那么FactoryPools
就执行create
创建对象。如果在SynchronizedPool
里面取到了,就从它的HashMap
里面取出这个对象,然后把HashMap
的最后一个项删掉。到这里取得操作执行完了。现在执行释放得操作。当某个对象要被释放了,不用了,那么就执行FactoryPools
的release
方法,这个方法会调用SynchronizedPool
的release
操作,将这个被释放的对象缓存起来,保存在HaseMap
里面。好了释放的操作完成了。当然缓存的大小肯定是有限制的,不能不限缓存。
如果在以后的项目里面你有出现会频繁创建对象的操作的时候,可以使用Glide
的这部分知识,更高效的重用已经创建过的对象。代码可以直接抄:FactoryPools
SynchronizedPool
可以直接用。