1700474616
1700474617
//从工厂中获得一个对象
1700474618
1700474619
SignInfo signInfo=SignInfoFactory.getSignInfo();
1700474620
1700474621
//进行其他业务处理
1700474622
1700474623
}
1700474624
1700474625
}
1700474626
1700474627
就这么简单,但是简单为什么会出现问题呢?而且这样写也没有问题呀,很标准的工厂方法模式,应该不会有大问题,然后又看了看系统厂商提供的分析报告,报告中指出:内存突然由800MB飙升到1.4GB,新的对象申请不到内存空间,于是出现OutOfMemory,同时报告中还列出宕机时刻内存中的对象,其中SignInfo类的对象就有400MB,疯子,绝对是疯子!报告都没有看嘛!
1700474628
1700474629
问题找到了,我拉郎当过来谈话,“厂商不是分析出原因了嘛,人家已经指出SignInfo类的对象占用了400多MB的内存,这是怎么回事?”
1700474630
1700474631
“三哥,这是很正常的,这么大的访问量,产生出这么多的SignInfo对象也是应该的,内存中有这么多对象并不表示这些对象正在被使用呀,估计很大一部分还没有被回收而已,垃圾回收器什么时候回收内存中的对象这是不确定的。你看,并发200多个,这可是并发数量……”
1700474632
1700474633
我想了想,也确实是这么回事。既然已经定位是内存中对象太多,那就应该想到使用一种共享的技术减少对象数量,那怎么共享呢?
1700474634
1700474635
大家知道,对象池(Object Pool)的实现有很多开源工具,比如Apache的commons-pool就是一个非常不错的池工具,我们暂时还用不到这种重量级的工具,我们自己来设计一个共享对象池,需要实现如下两个功能。
1700474636
1700474637
❑容器定义
1700474638
1700474639
我们要定义一个池容器,在这个容器中容纳哪些对象。
1700474640
1700474641
❑提供客户端访问的接口
1700474642
1700474643
我们要提供一个接口供客户端访问,池中有可用对象时,可以直接从池中获得,否则建立一个新的对象,并放置到池中。
1700474644
1700474645
设计思路有了,那我们池中对象的标准是什么呢?你想想看,如果你把所有的对象都放到池中,那还有什么意义?内存早就给你撑爆了!这么多对象,必然有一些相同的属性值,如几十万SignInfo对象中,考试科目就4个,考试地点也就是30多个,其他的属性则是每个对象都不相同的,我们把对象的相同属性提取出来,不同的属性在系统内进行赋值处理,是不是就可以建立一个池了?话无须多说,我们以类图来表示,如图28-2所示。
1700474646
1700474647
1700474648
1700474649
1700474650
图28-2 增加对象池的类图
1700474651
1700474652
做一个很小的改动,增加了一个子类,实现带缓冲池的对象建立,同时在工厂类上增加了一个容器对象HashMap,保存池中的所有对象。我们先来看产品子类,如代码清单28-4所示。
1700474653
1700474654
代码清单28-4 带对象池的报考信息
1700474655
1700474656
public class SignInfo4Pool extends SignInfo{
1700474657
1700474658
//定义一个对象池提取的KEY值
1700474659
1700474660
private String key;
1700474661
1700474662
//构造函数获得相同标志
1700474663
1700474664
public SignInfo4Pool(String_key){
1700474665
[
上一页 ]
[ :1.700474616e+09 ]
[
下一页 ]