美文网首页代码优化Android知识Android开发
使用对象池Pools,优化频繁创建和销毁的代码

使用对象池Pools,优化频繁创建和销毁的代码

作者: InKenKa | 来源:发表于2017-02-16 21:28 被阅读409次

    前言

    在阅读Glide源码时,发现Glide大量使用对象池Pools来对频繁需要创建和销毁的代码进行优化。

    比如Glide中,每个图片请求任务,都需要用到 EngineJob 、DecodeJob类。若每次都需要重新new这些类,并不是很合适。而且在大量图片请求时,频繁创建和销毁这些类,可能会导致内存抖动,影响性能。

    Glide使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能。


    代码介绍

    1. 用到的类
    android.support.v4.util.Pool

    2. Pool接口类
    acquire(): 从对象池请求对象的函数:
    release(): 释放对象回对象池的函数

    public static interface Pool<T> {
    
        public T acquire();
        
        public boolean release(T instance);
    }
    

    3. Android官方对象池的简单实现:SimplePool,也是用得最多的实现
    原理:使用了“懒加载”的思想。当SimplePool初始化时,不会生成N个T类型的对象存放在对象池中。而是当每次外部调用release()时,才把释放的T类型对象存放在对象池中。要先放入,才能取出来。

    public static class SimplePool<T> implements Pool<T> {
        private final Object[] mPool;
        private int mPoolSize;
        
        public SimplePool(int maxPoolSize) {
            if (maxPoolSize <= 0) {
                throw new IllegalArgumentException("The max pool size must be > 0");
            }
            mPool = new Object[maxPoolSize];
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public T acquire() {
            if (mPoolSize > 0) {
                final int lastPooledIndex = mPoolSize - 1;
                T instance = (T) mPool[lastPooledIndex];
                mPool[lastPooledIndex] = null;
                mPoolSize--;
                return instance;
            }
            return null;
        }
    
        @Override
        public boolean release(T instance) {
            if (isInPool(instance)) {
                throw new IllegalStateException("Already in the pool!");
            }
            if (mPoolSize < mPool.length) {
                mPool[mPoolSize] = instance;
                mPoolSize++;
                return true;
            }
            return false;
        }
    
        private boolean isInPool(T instance) {
            for (int i = 0; i < mPoolSize; i++) {
                if (mPool[i] == instance) {
                    return true;
                }
            }
            return false;
        }
    }
    

    4. 对SynchronizedPool的简单封装
    由于对象池设计是要先放入,才能取出来。所以当没有放入对象时,调用acquire(),返回都是null,所以可以对 对象池进行以下封装,方便其使用:

    public class MyPooledClass {
      private static final SynchronizedPool<MyPooledClass> sPool =
              new SynchronizedPool<MyPooledClass>(10);
    
      public static MyPooledClass obtain() {
          MyPooledClass instance = sPool.acquire();
          return (instance != null) ? instance : new MyPooledClass();
      }
    
      public void recycle() {
          sPool.release(this);
      }
    }
    

    相关文章

      网友评论

        本文标题:使用对象池Pools,优化频繁创建和销毁的代码

        本文链接:https://www.haomeiwen.com/subject/lmyhwttx.html