享元模式:减少内存占用的诀窍

这篇具有很好参考价值的文章主要介绍了享元模式:减少内存占用的诀窍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一,概要

享元模式(Flyweight Pattern)是一种结构型设计模式,它主要通过共享对象来降低系统中对象的数量,从而减少内存占用和提高程序性能。这听起来有点像单例模式,但它们在实现和用途上有很大的区别。享元模式的核心是把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。享元模式的本质是缓存共享对象,降低内存消耗。

  • 内部状态:内部状态是对象可共享的部分,它存储在享元对象内部,并且不随外部环境的变化而变化。内部状态可以被多个具体享元对象共享。
  • 外部状态:外部状态是对象的上下文相关部分,它在使用时动态传入享元对象,并且随外部环境的变化而变化。外部状态不可共享,每个具体享元对象都需要接收外部状态作为参数来完成其操作。

享元模式三大角色

  • 享元接口:定义了享元对象的公共方法,这些方法可以操作享元对象的外部状态,外部状态一般作为方法参数传入。

  • 具体享元类:实现享元接口,完成具体的对象操作。内部状态作为成员属性存在,一旦初始化完成就不再改变,不对外提供setter方法。

  • 享元工厂:负责创建和管理享元对象。当客户端请求一个享元对象时,享元工厂会检查是否有已经创建的享元对象,如果有,则直接返回;如果没有,则创建一个新的享元对象并加入到享元池中。

优点

  1. 减少内存占用:相同对象只要保存一份,大大降低了系统中对象的数量。
  2. 提高性能:享元模式减少了对象的创建和销毁,降低了垃圾回收的开销,从而提高了程序性能。
  3. 提高可扩展性:通过外部状态的引入,享元模式可以灵活地处理不同的上下文,使得系统更具可扩展性。

缺点

  1. 复杂度增加:享元模式需要将对象的状态进行拆分,引入了内部状态和外部状态的管理,增加了系统的复杂性。

  2. 线程安全问题:由于享元对象是共享的,因此在多线程环境下,对享元对象的操作需要考虑线程安全。

适用场景

  • 系统中存在大量细粒度的对象,且这些对象的状态可以分为内部状态和外部状态时,可以考虑使用享元模式。
  • 对象的大部分状态可以共享,而一小部分状态需要外部环境来改变时,可以使用享元模式。
  • 需要缓存对象以提高系统性能,并且可以接受一定的对象复用时,可以使用享元模式。
  • 需要对对象进行池化管理,以便于统一控制和管理对象的创建、销毁和状态维护时,可以考虑使用享元模式。

二,实现案例

假设我们需要在一个坐标图纸上,绘制100个固定半径的圆,圆分为三种颜色。常规方法,我们定义一个圆,里面包含半径,颜色,横坐标,纵坐标四个属性,再定义一个绘制的方法draw(),然后我们创建100个对象,调用draw()方法就可以实现。但是如果我们用享元模式实现,仅需创建3个对象即可,其关键就是将颜色和半径作为内部状态共享,将坐标作为外部状态分离出来。

步骤1:创建享元接口Shape

public interface Shape {
    //x,y表示坐标
    void draw(int x,int y);
}

步骤2:创建具体享元类Circle

public class Circle implements Shape{
    private String color;
    private int radius;

    public Circle(String color){
        this.color = color;
        this.radius = 10;
    }

    @Override
    public void draw(int x,int y) {
        System.out.println("--在坐标("+x+","+y+")处画圆: [颜色 : " + color
                +", 半径 :" + radius+"]");
    }
}

步骤3:创建享元工厂ShapeFactory

public class ShapeFactory {
    private static final HashMap<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        Circle circle = (Circle)circleMap.get(color);
        System.out.println("从缓存中获取"+color+"色的圆");

        if(circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle);
            System.out.println("缓存中不存在,先创建"+color+"色的圆,并放入缓存中");
        }
        return circle;
    }
}

步骤4:客户端测试

public class Client {
    private static final String colors[] = { "Red", "Green", "Blue" };

    public static void main(String[] args) {
        for(int i=0; i < 10; ++i) {
            Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());
            circle.draw(getRandomX(),getRandomY());
        }
    }

    private static String getRandomColor() {
        return colors[(int)(Math.random()*colors.length)];
    }
    private static int getRandomX() {
        return (int)(Math.random()*100 );
    }
    private static int getRandomY() {
        return (int)(Math.random()*100);
    }
}

测试结果

享元模式:减少内存占用的诀窍

三,总结

享元模式是一种非常实用的设计模式,它的思想很简单,就是把一些可以共享的对象只创建一份,放入到缓存池中,供业务方引用。这样做可以大大减少对象的创建开销,减少内存中相似或相同对象的数量,减少内存占用。在java源码中也有很多享元模式的思想体现,如String的字符串常量池,Integer包装类中的IntegerCach,以及各种连接池,线程池等技术。我们在日常开发过程中,可以结合上下文场景,灵活运用享元模式,但需要注意线程安全性和共享池的管理。

最后,希望这篇文章能对大家有所帮助,如果你喜欢这篇文章,不妨点个赞和分享给你的朋友们。欢迎大家在评论区留言交流,我们下次再见!👋
享元模式:减少内存占用的诀窍文章来源地址https://www.toymoban.com/news/detail-475833.html

到了这里,关于享元模式:减少内存占用的诀窍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TextBrewer:融合并改进了NLP和CV中的多种知识蒸馏技术、提供便捷快速的知识蒸馏框架、提升模型的推理速度,减少内存占用

    TextBrewer 是一个基于PyTorch的、为实现NLP中的 知识蒸馏 任务而设计的工具包, 融合并改进了NLP和CV中的多种知识蒸馏技术,提供便捷快速的知识蒸馏框架,用于以较低的性能损失压缩神经网络模型的大小,提升模型的推理速度,减少内存占用。 TextBrewer 为NLP中的知识蒸馏任务

    2024年02月13日
    浏览(43)
  • C++享元模式探索:轻松优化内存使用和性能提升之道

    享元模式(Flyweight Pattern)是一种结构型设计模式,其主要目的是通过共享相似对象以减少内存占用和提高程序性能。在享元模式中,相似对象的公共部分被提取出来,并存储在共享的享元对象中。每个实例对象只需存储其特有的状态,而公共状态则从享元对象中获取。这样

    2023年04月23日
    浏览(52)
  • Docker目录占用了太多空间, 如何减少占用?

    如果你的Docker目录占用了太多空间,你可以尝试以下几种方法来减少它的大小: 删除不再使用的镜像、容器、数据卷和网络。你可以使用sudo  docker system prune 命令来删除所有未使用的对象。 清理日志文件。Docker容器会生成日志文件,这些文件可能会占用大量空间。你可以定

    2024年02月17日
    浏览(43)
  • LabVIEW使用数据引用减少内存

    概览 NI LabVIEW 省略了 开发 软件时 需要 手动 管理 内存。LabVIEW 编译器 始终 会 分析 您 的 代码, 以 确定 如何 优 化 性能 并 减少 所需 的 内存 量。但是, 想要 更多 控制 内存 分配 的 高级 用户 可以 在 LabVIEW 2009 中创建 数据 引用。 内容 背景 基本示例 对类使用引用 其他

    2024年02月16日
    浏览(39)
  • Node.js使用jemalloc内存分配器显著减少内存使用

    前言 Node.js 默认使用的是 ptmalloc(glibc) 内存分配器,而: 在服务端领域「不会选择默认的 malloc」是一个常识 。( 来源 ) ptmalloc 的分配效率较低( 来源 ),对于 长时间、多核 / 多线程 运行的程序( 来源 ),特别适合使用 jemalloc 分配器,使用 jemalloc 分配内存可以更好的处

    2024年02月03日
    浏览(39)
  • 设计模式-享元模式

    享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少创建大量相似对象对内存资源的消耗,通过共享这些对象来提高程序性能和系统资源利用率。在实际应用场景中string就是使用了享元模式,string a = “123”; string b = “123”; 我们假设有一个场景是需要创建大量的

    2024年01月24日
    浏览(43)
  • 构型模式-享元模式

    描述 通过共享已经存在的对象来减少对象的数量,从而提高系统的性能和效率。这种方式可以避免重复创建对象,同时也能够降低内存消耗。 适用环境 当需要创建大量细粒度的对象时使用;对象的状态可以被多个对象共享时使用。 优点: 可以大幅度减少系统中对象的数量

    2023年04月16日
    浏览(33)
  • 设计模式——享元模式

    享元模式(Flyweight Pattern)是池技术的重要实现方式。 使用共享对象可以有效地支持大量的细粒度对象。 优点 可以大大减少应用程序创建对象的数量,降低程序内存占用。 缺点 提高了系统的复杂度,需要分离出享元对象的外部状态(key)和内部状态(对象属性),并且外部

    2024年02月16日
    浏览(39)
  • 设计模式:享元模式

    首先我们需要简单了解一下什么是享元模式。 享元模式(Flyweight Pattern) :主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式的重点就在这个享字,通过一些共享技术来减少对象的创建,实际上Java中String值的存储,Volley中的 ByteArrayPool 也使用到了享元模式,

    2024年02月08日
    浏览(44)
  • 设计模式(22)享元模式

    一、介绍: 1、定义:享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。 2、组成结构: (1)Flyweight(抽象享元类):通常是一个接口或

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包