博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flyweight享元模式(结构型模式)
阅读量:5876 次
发布时间:2019-06-19

本文共 2099 字,大约阅读时间需要 6 分钟。

1、面向对象的缺点 

虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能。但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如下:

///         /// Word文字的Font样式        ///         public class Font //8+8(继承object的虚表指针4个字节、垃圾收集同步占4个字节)=16个字节        {            public Font(string fontName, int size)            {                _fontName = fontName;                _size = size;            }            string _fontName;//4个字节,但是由于字符串留用技术,可能实际创建大量这个对象的时候,可能会节省一些空间            int _size;//4个字节        }        ///         /// Word文字对象        ///         public class Charactor //2+4(Font类型的引用指针)+16+2(32位操作系统的内存补齐)+8个字节(继承object的虚表指针4个字节、垃圾收集同步占4个字节)=32个字节        {            public Charactor(char c, Font font)            {                _c = c;                _font = font;            }            char _c;//为一个Unicode字符,16位,占2个字节            Font _font;//16个字节        }

调用代码如下:

public class ThirdSystem        {            public void Run()            {                long a = GC.GetTotalMemory(true);                //创建10000000个Charactor对象大概要消耗32*10000000/1024/1024=343M                int num = 10000000;                //创建1千万个Charactor对象                var list = new List
();//不消耗内存,如果使用ArrayList并指定初始化长度,会产生内存消耗 for (var i = 0; i < num; i++) { Charactor charactor = new Charactor('c', new Font("宋体", 6)); list.Add(charactor); } long b = GC.GetTotalMemory(true); long memoryConsume = b - a; Console.WriteLine(memoryConsume / 1024 / 1024);//实际输出369,实际创建10000000个Charactor对象消耗了369M的内存空间 } }

在客户端系统生成了一千万个对象实例,最后产生了369M的内存开销,还单单是一个对象的实例的开销,这种方式显然不可取.

 

2、问题

采用对象方法来创建大量的对象实例,产生了很高的运行时代价-主要指内存方面的,那么如何在采用面向对象的方式生成大量对象实例的同时,避免这种开销呢?

关于这个问题,字符串留用池的实现方式.提供了很好的借鉴.关于具体实现思路,请参考

 

3、解决方案

 

4、使用Flyweight享元模式的要点

(1)、该模式不涉及抽象性问题,也就是和抽象无关,它主要是解决面向对象的代价问题,在面向对象的过程中,创建了大量的对象实例,所产生的内存消耗.

(2)、该模式采用共享对象实例的方式来降低系统中对象的个数,也就是通过Hashtable等持有相同对象的引用降低细粒度对象实例带给系统的压力

(3)、因为采用持有相同对象引用的方式来共享对象,所以当一个对象发生改变时,所有的对象都会发生改变,类似数组,所以要注意对象状态的处理,不能盲目的修改.

(4)、该模式最好计算下整个系统的开销,在根据实际情况去判断是否要采用享元模式.

 

转载地址:http://zqzix.baihongyu.com/

你可能感兴趣的文章
android aapt 用法 -- ApkReader
查看>>
[翻译]用 Puppet 搭建易管理的服务器基础架构(3)
查看>>
Android -- AudioPlayer
查看>>
Python大数据依赖包安装
查看>>
Android View.onMeasure方法的理解
查看>>
Node.js 爬虫初探
查看>>
ABP理论学习之仓储
查看>>
NestJS 脑图
查看>>
我的友情链接
查看>>
Html body的滚动条禁止与启用
查看>>
Tengine新增nginx upstream模块的使用
查看>>
多媒体工具Mediainfo
查看>>
1-小程序
查看>>
CentOS图形界面和命令行切换
查看>>
HTML5通信机制与html5地理信息定位(gps)
查看>>
Mind_Manager_2
查看>>
手动升级 Confluence - 规划你的升级
查看>>
汽车常识全面介绍 - 悬挂系统
查看>>
电子政务方向:We7.Cloud政府云门户
查看>>
虚拟机Centos7连接Internet
查看>>