前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >十、享元模式

十、享元模式

作者头像
Yuyy
发布2022-09-21 10:00:42
1840
发布2022-09-21 10:00:42
举报
文章被收录于专栏:yuyy.info技术专栏

Flyweight

定义

共享存储单元,节约内存空间。

使用场景

例如文本编辑器里,每个字符都有字体大小,显示颜色,背景颜色等属性。将这些属性抽取为字体,每个字体的属性在内存中只保留一份即可。感觉和CSS挺像的,不过享元模式侧重点不是代码复用,而是对象复用。

JDK里使用的地方

Integer缓存

int类型在自动装箱时,调用java.lang.Integer#valueOf(int)

代码语言:javascript
复制
    public static Integer valueOf(int i) {
        // 如果在缓存范围内
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            // 直接返回缓存中的对象
            return IntegerCache.cache[i + (-IntegerCache.low)]; 
        return new Integer(i);
    }

IntegerCache是Integer的私有静态内部类

代码语言:javascript
复制
    private static class IntegerCache {
        // 缓存范围低位是固定的
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // 高位默认127,可配置
            // high value may be configured by property
            int h = 127;
            // 读取JVM参数
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // 解析配置的参数为数字失败时,没有任何提示
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            // 第一次调用java.lang.Integer#valueOf(int)时才初始化,实例化缓存范围内的所有对象,和String的缓存机制不同
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

String缓存

通过字面量的形式创建字符串时,jvm会先在字符串常量池中查找是否有相同内容的字符串,如果要,就返回其引用。否则就创建字符串对象,并存入字符串常量池里。

字符串常量池的位置

在JDK 7以前的版本中,字符串常量池是放在永久代中的。 因为按照计划,JDK会在后续的版本中通过元空间来代替永久代,所以首先在JDK 7中,将字符串常量池先从永久代中移出,暂时放到了堆内存中。 在JDK 8中,彻底移除了永久代,使用元空间替代了永久代,于是字符串常量池再次从堆内存移动到永久代(元空间)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-9-25 1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Flyweight
    • 定义
      • 使用场景
        • JDK里使用的地方
          • Integer缓存
          • String缓存
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档