• 设计模式学习(十二):享元模式


    设计模式学习(十二):享元模式

    作者:Grey

    原文地址:

    博客园:设计模式学习(十二):享元模式

    CSDN:设计模式学习(十二):享元模式

    享元模式#

    享元模式是一种结构型模式。

    一个应用场景是:运用共享技术有效地支持大量细粒度的对象。主要解决

    在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

    假设我们有一个子弹类,同时我们设计一个子弹池,子弹池负责提供子弹

    public class BulletPool {
        List bullets = new ArrayList<>();
        {
            for (int i = 0; i < 10; i++) {
                bullets.add(new Bullet(true));
            }
        }
        public Bullet getBullet() {
            for (int i = 0; i < bullets.size(); i++) {
                if (bullets.get(i).living) {
                    return bullets.get(i);
                }
            }
            return new Bullet(true);
        }
    }
    

    可以看到 getBullet 逻辑,如果池子中有子弹,就拿池中的子弹,如果没有,就 new 一个新的子弹返回。

    上述示例的 UML 图如下

    image

    享元模式应用

    • 使用对象池对高并发下的内存进行管理

    对于开发者来说,垃圾回收是不可控的,而且是无法避免的。但是,我们还是可以通过一些方法来降低垃圾回收的频率,减少进程暂停的时长。我们知道,只有使用过被丢弃的对象才是垃圾回收的目标,所以,我们需要想办法在处理大量请求的同时,尽量少的产生这种一次性对象。最有效的方法就是,优化你的代码中处理请求的业务逻辑,尽量少的创建一次性对象,特别是占用内存较大的对象。比如说,我们可以把收到请求的 Request 对象在业务流程中一直传递下去,而不是每执行一个步骤,就创建一个内容和 Request 对象差不多的新对象。这里面没有多少通用的优化方法。对于需要频繁使用,占用内存较大的一次性对象,我们可以考虑自行回收并重用这些对象。实现的方法是这样的:我们可以为这些对象建立一个对象池。收到请求后,在对象池内申请一个对象,使用完后再放回到对象池中,这样就可以反复地重用这些对象,非常有效地避免频繁触发垃圾回收。

    • Java 中 Boolean 类的valueOf(boolean b) 方法 ,这个方法返回的 Boolean 对象不会新 new 出来,而是复用的同一个, 源码如下:
    public static Boolean valueOf(boolean b){
        return(b?TRUE:FALSE);
    }
    public static final Boolean TRUE=new Boolean(true);
    public static final Boolean FALSE=new Boolean(false);
    
    • Netty 中的 Buffer 分配。

    • 连接池管理,例如:Apache Commons Pool

    • Java SE 中的 IntegerCache 类和 String 类

    在 Java Integer 的实现中, -128 到 127 之间的整型对象会被事先创建好,缓存在 IntegerCache 类中。当我们使用自动装箱或者valueOf()来创建这个数值区间的整型对象时,会复用 IntegerCache 类事先创建好的对象。这里的 IntegerCache 类就是享元工厂类,事先创建好的整型对象就是享元对象。在Java 中的 String 类的实现中,JVM 开辟一块存储区专门存储字符串常量,这块存储区叫作字符串常量池,类似于 Integer 中的 IntegerCache 。不过,跟IntegerCache 不同的是,它并非事先创建好需要共享的对象,而是在程序的运行期间,根据需要来创建和缓存字符串常量。

    注:Java 提供了两个配置 IntegerCache 的参数

    //方法一:
    -Djava.lang.Integer.IntegerCache.high=255
    //方法二:
    -XX:AutoBoxCacheMax=255
    

    UML 和 代码#

    UML 图

    代码

    更多#

    设计模式学习专栏

    参考资料#

  • 相关阅读:
    误差反向传播法原理
    【宠粉赠书】科技图表绘制:R语言数据可视化
    Python Flask框架 入门详解与进阶
    我们这一代人的机会是什么?
    OpenGL ES视频特效开发参考Shadertoy参数详解参考Godot文档
    js 多个小程序之间互相跳转,a小程序带参跳转到b小程序中
    MongoDB数据库新手入门
    规范的企业开发常需要的配置文件-Python开发技巧XI
    一套次世代建模的流程是怎样的?
    javascript追加标签
  • 原文地址:https://www.cnblogs.com/greyzeng/p/16880631.html