设计背景

每个平台都会有用户这种基础数据的设计,作为最基础的用户,每个用户都有很多属性,比如性别,姓名,手机号等,每个用户还可以有类似经验值这样的荣誉系统,根据不同的经验值来对应不同的等级,不同的等级对应不同的荣誉UI,比如一级用户可能只显示一个星星,二级用户显示两颗星星,以此类推,类似于QQ等级的星星月亮太阳,这样的荣誉系统随着平台的不断壮大,可能会衍生出很多类型。那么问题来了,用户登录的时候就需要初始化用户的这些荣誉值,以星星数为例,类似于以下代码

public class Star

{

//等级

public int Level{get ;set ;}

//对应的星星数目

public int StarNumber{get ;set ;}

//对应的星星颜色

public int Color{get ;set ;}

... 其他属性

}

//用户信息

public class User{

public Star StarInfo{get ;set ;}

//...用户的其他属性

}

//初始化用户信息

User u=new User(){ StarInfo=new Star(){ Level=1, StarNumber=1,Color=1}};

每一个登录用户都会初始化一个Star属性来表示当前用户的Star信息,当有100万用户甚至更多用户同时在线的时候,内存中就实例化了同样数量的Star对象,以及其他类似的属性对象。这么多重复的对象难道不能优化吗?当然不是!!

问题分析

一个业务出现问题,首先要分析问题的所在。根据以上所说,问题的根本在于产生了大量的对象,首先每个用户对象都有自己独特的状态,这个基本上不可能分解优化,但是类似Star这样的属性就有优化途径了,这些荣誉属性一个最大的共同点就是不可变,换句话说,等级1的用户对应的Star信息是永远不会变的,永远是level=1,starnumber=1,color=1 等。基于这个不变性,我们可以把这个Star抽离出来,供所有等级1的用户使用,假设原来有10万等级1的用户,原来需要10万个对象,现在只需要一个对象,这可是天壤之别。

解决问题

基于以上问题分析,我们需要做的是把对象重复使用,只要是对象重复问题,基本上可以利用一个对象出口来解决问题,类似于以下的对象初始化工厂,但是要注意线程安全问题,因为同时请求并初始化对象的线程会有多个。

public class UserStarFac

{

static object objLock = new object();

static Dictionary UserStarMap = new Dictionary();

public static Star GetUserStar(int level)

{

//利用锁来防止实例化多次,当然这里可以优化

lock (objLock)

{

Star info = null; ;

if(!UserStarMap.TryGetValue(level, out info))

{

info = new Star() { Color = 1, Level = 1, StarNumber = 1 };

UserStarMap.Add(level,info);

}

return info;

}

}

}

编写简单测试程序

static void Main(string[] args)

{

int i = 0;

List userList = new List();

while (i < 100000)

{

// userList.Add(new User() { StarInfo=new Star() { Color=1, Level=1, StarNumber=1} });

userList.Add(new User() { StarInfo= UserStarFac .GetUserStar(1)});

i++;

}

Console.WriteLine("初始化完成");

Console.Read();

}

内存的测试结果:

不执行任何程序:占用内存:2.8 M

无优化初始化10万对象:占用内存:11 M

优化之后初始化10万对象:占用内存:7 M

居然一个小小的优化就减少了4M内存,不要小看这小小的4M,你要看的是比例,居然减少了将近 50%,真实业务中,可以进行这种优化的地方数不胜数,不知道你是否在乎呢?

这种大量重复对象的问题尤其是在游戏编程中经常存在,比如五子棋游戏,棋子的初始化,一个游戏大厅存在成千上百万对局,如果每个局中的棋子都初始化一个对象,那内存使用是相当可怕的,这种需要把通用的对象属性,不变的对象属性抽离出来,做共享是有必要的。

据说这种优化有一个学名:享元模式,没有必要记住名字,但需要记住原理和场景,必须要提一句:注意不变的对象才可以哦

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[程序员羽化之路--假如需要一百万个对象]http://www.zyiz.net/tech/detail-120763.html

java 羽化_程序员羽化之路--假如需要一百万个对象相关推荐

  1. json java 数据类型_程序员都应该了解的一种数据格式之 JSON

    原标题:程序员都应该了解的一种数据格式之 JSON 作者 | 猪哥 责编 | maozz JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Doug ...

  2. java情人节_程序员也是有情怀的!情人节看程序员如何告白

    一年一度的情人节又来了,我们程序员也是有情怀,懂浪漫的,富有理想主义的一个族群,智商超越常人,当人表白的方式也是普通人难以学习的. 记得某年圣诞节上,西班牙程序员Roman Cortes带来了用纯ja ...

  3. Java对联_程序员专属对联

    猿 份 因程序汇聚 因猿份相识 对联一 上联:上拜图灵只佑服务可用 下联:下跪关公但求永不宕机 横批:风调码顺 风调雨顺 上拜图灵只佑服务可用 下跪关公但求永不宕机 对联二 上联:屏中创造繁华世 下联 ...

  4. Java对联_程序员的春节对联集锦

    上联:为系统而生,为框架而死,为debug奋斗一辈子! 下联:吃符号的亏,上大小写的当,最后死在需求上! 横批:杯具程序员. 上联:算法数据思路清晰 下联:编译链接一气呵成 横批:码到功成 上联:思前 ...

  5. 参数调优为什么要采样_程序员精进之路:性能调优利器--火焰图

    本文主要分享火焰图使用技巧,介绍 systemtap 的原理机制,如何使用火焰图快速定位性能问题原因,同时加深对 systemtap 的理解. 让我们回想一下,曾经作为编程新手的我们是如何调优程序的? ...

  6. 增删改查java代码_程序员:听说你正在为天天写增删改查代码而烦恼

    有相当多的一部分程序员一直都只接触业余应用的功能,天天写业务代码的程序员也被戏称为CURD程序员,CURD就是增(create).改(update).查(read).删(delete)的意思. CUR ...

  7. java 代码 _程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

    1.曾经不止一次在生产中见过类似这样的代码: 这有很多变种,例如用 Integer.valueOf(1). (Integer)1 之类的,那些细节都不重要.重要的是:凭空用一个 Integer 对象作 ...

  8. java 浪漫_程序员的浪漫:用 java 实现每天给对象法发情话

    一.引言 最近看到一篇用js代码实现表白的文章,深有感触. 然后发现自己也可以用java代码实现,然后就开始写代码了,发现还挺有意思的,话不多说开搞 实现思路: 使用HttpClient远程获取彩虹屁 ...

  9. 不认识java代码_程序员进阶:优雅的代码对于一个架构师的重要性

    lison:复旦大学工程硕士,专注技术十年,产品控.代码控,拥有丰富的项目经验,主持研发了多个成功上线的大型互联网项目.热爱互联网,热衷于各种web技术,精通JAVA.J2EE和前端开发,擅长互联网高 ...

最新文章

  1. 数据结构和算法:全面的算法代码库
  2. Netty详解(二)Linux 网络IO模型
  3. RuntimeError: Error occured during execution of the processing block! See the log for more info
  4. Spring中Bean的后置处理器
  5. 普通交换机不需要任何设置,也不能设置
  6. IBASE hierarchy structure and related API
  7. plc采用计算机结构如何理解,PLC的基本结构
  8. mysql1714_linux环境安装mysql
  9. 动手学深度学习(PyTorch实现)(三)--过拟合与欠拟合
  10. JMeter中持续时间设置成永远调度器才会起作用
  11. 关于atollic truestudio for stm32
  12. 检测到JSON.NET错误类型的自引用循环
  13. Mac鼠标增强软件Bettertouchtool
  14. 企业邮箱怎么弄企业邮箱是什么邮箱求一个企业邮箱账号
  15. 基于S52单片机的温度测量与报警装置
  16. js获取前后三个月的时间戳
  17. SpringBoot 雪花算法生成商品订单号【SpringBoot系列13】
  18. Ionic入门学习(一)
  19. vim中指定字符串的替换和删除
  20. Control.Invoke用法注意事项

热门文章

  1. 使用Scrapy框架爬取88读书网小说,并保存本地文件
  2. Java实现 蓝桥杯VIP 算法提高 洗牌
  3. osx制作u盘安装盘
  4. 【springboot】jasypt加密
  5. 【NLP】LTP中文工具集使用
  6. 来个大佬帮看下这个密文如何解密
  7. 成组链接法 恩赐解脱
  8. DOSBox使用debug
  9. dva model里面的effects函数可以调用effects函数
  10. Raid常见级别(Raid 0、Raid 1、Raid 5、Raid 10)