测试享元模式是否有助与系统提高性能

//测试对象
public class Tree {
	//外部状态
	private int xCoord,yCoord,age;

	public Tree(int xCoord, int yCoord, int age) {
		super();
		this.xCoord = xCoord;
		this.yCoord = yCoord;
		this.age = age;
	}
	//内部状态
	public void display() {
		//
	}
}
-------------------------------------------

**
 * 测试类,创建1千万个对象,查看对内存的消耗情况。
 * @author 34wei12-34
 *
 */
public class TreesTest {

	private int length = 10000000;
	
	private Tree[] treelt = new Tree[length];

	public TreesTest() {
		for(int i = 0 ;i < length ;i++) {
			treelt[i] = new Tree((int)(Math.random()*length),
					(int)(Math.random()*length),(int)(Math.random()*length)%5);
		}
	}
	
	public void display() {
		for(int i = 0 , len = treelt.length;i < len;i++) {
			treelt[i].display();
		}
	}
}
------------------------------------------
//客户端
public class MainTest {

	public static void main(String[] args) {
		memoryInfo();//初始化内存的占用情况
		TreesTest  trees = new TreesTest();
		memoryInfo();//创建对象后,内存的占用情况,创建对象消耗时间
		trees.display();
		memoryInfo();
	}
	
	public static void memoryInfo() {
		//最大内存:maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存
		long max = Runtime.getRuntime().maxMemory();
		//分配内存:totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,
		//也就是java虚拟机这个进程当时所占用的所有 内存。
        //已占用内存:在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,
		long total = Runtime.getRuntime().totalMemory();
		//已分配内存中剩余的空间
        //但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),
		//所以freeMemory()的值一般情况下都是很小的
		long free = Runtime.getRuntime().freeMemory();
		
		
		long used = total - free;
		
		System.out.println("最大内存 = " + max);
		System.out.println("已分配内存 = " + total);
		System.out.println("已分配内存中的剩余空间 = " + free);
		System.out.println("已用内存 = " + used);
		System.out.println("时间 = " + System.currentTimeMillis());
		System.out.println("");
		
	}
}

初始内存

最大内存 = 1888485376
已分配内存 = 128974848
已分配内存中的剩余空间 = 126929792
已用内存 = 2045056
时间 = 1550287881701

第一次创建对象

最大内存 = 1888485376
已分配内存 = 566231040
已分配内存中的剩余空间 = 285112856
已用内存 = 281118184
时间 = 1550287889171

第二次创建对象

最大内存 = 1888485376
已分配内存 = 566231040
已分配内存中的剩余空间 = 285112856
已用内存 = 281118184
时间 = 1550287889181

数据解析:从上面的数据可以看到对象的创建花费了大量内存,也耗费了大量的时间。有内存和耗费时间考虑使用数据分享技术,降低对象的创建个数,从而减少内存和运行时间的消耗。

 

下面使用享元模式:

/**
 * 享元抽象角色
 */
public interface Plant {
	//为这个共享函数创建抽象的享元
	public void display(int x,int y,int age);
}
--------------------------------------
//具体享元类
public class Grass implements Plant {

	//享元模式中需要获取外部状态。这里直接传递参数,也可以将这些对象封装成对象传递进来。
    //在这里面对传递的非享元类进行操作,然后返回我们期望的结果
	public void display(int x, int y, int age) {
		//对传进来的外部状态进行处理。
	}

}

//具体享元类
public class Tree implements Plant {

	@Override
	public void display(int x, int y, int age) {
		//处理传递进来的外部状态
	}

}
----------------------------------------
//享元工厂类
public class FlyweigthFactory {

//创建一个存放享元类的池对象	
private Map<Integer,Plant> pool;

	public FlyweigthFactory() {
		pool = new HashMap<Integer,Plant>();
	}
	//根据外部对象获取我们需要的享元类
	public  Plant getPlant(int external) {
		
		if(!pool.containsKey(external)) {
			switch(external) {
			case 0 :
				pool.put(0, new Tree()); 
				break;
			case 1 :
				pool.put(1, new Grass());
				break;
			}
		
		}
		return (Plant)pool.get(external);
	}

}
----------------------------------------------------
//使用享元工厂创建多个对象,进行测试创建对象内存好时间消耗情况
public class PlantManager {

	private int length = 10000000;
	private int[] xArray = new int[length], yArray = new int[length],
			AgeArray = new int[length],	typeArray = new int[length];
	
	private PlantFactory mPlantFactory;
	public PlantManager() {
		
		mPlantFactory=new PlantFactory();
		for (int i = 0; i < length; i++) {

			xArray[i] = (int) (Math.random() * length);
			yArray[i] = (int) (Math.random() * length);
			AgeArray[i] = (int) (Math.random() * length) % 5;
			typeArray[i]= (int) (Math.random() * length) % 2;
		}
	}
	
	public void displayTrees() {
		for (int i = 0; i < length; i++) {
			//从享元工厂中获取享元对象可以减少内存和运行时间的消耗
            mPlantFactory.getPlant(typeArray[i]).display(xArray[i], yArray[i], AgeArray[i]);
			}
	}
}
---------------------------------------
//客户端
public class MainTest {

	public static void main(String[] args) {
		memoryinfo();
		//创建不可共享对象
		PlantManage plant = new PlantManage();
		
		memoryinfo();
		//调用享元类
		plant.display();
		
		memoryinfo();
	}
	
	public static  void memoryinfo() {
		//最大内存
		long max = Runtime.getRuntime().maxMemory();
		//当前分配内存
		long total = Runtime.getRuntime().totalMemory();
		//分配内存中剩余内存
		long free = Runtime.getRuntime().freeMemory();
		//占用多少的分配内存
		long used = total - free;
		
		System.out.println("最大内存 = "+max);
		System.out.println("当前分配内存 = "+total);
		System.out.println("分配内存中剩余内存 = "+free);
		System.out.println("占用多少的分配内存 = "+used);
		System.out.println("耗费时间 = "+System.currentTimeMillis());
		System.out.println("");
		
	}
}

最大内存 = 1888485376
已分配内存 = 128974848
已分配内存中的剩余空间 = 126930104
已用内存 = 2044744
时间 = 1550297830681

最大内存 = 1888485376
已分配内存 = 209715200
已分配内存中的剩余空间 = 47670392
已用内存 = 162044808
时间 = 1550297831983

最大内存 = 1888485376
已分配内存 = 209715200
已分配内存中的剩余空间 = 47670392
已用内存 = 162044808
时间 = 1550297832126

 

两次结果进行对比:

 

初始内存                            使用享元模式

最大内存 = 1888485376  最大内存 = 1888485376

已分配内存 = 128974848  已分配内存 = 128974848

已分配内存中的剩余空间= 126929792  已分配内存中的剩余空间 = 126930104

已用内存 = 2045056    已用内存 = 2044744

时间 = 1550287881701   时间 = 1550297830681

在初始化过程中,使用享元模式消耗的时间和占用的内存都比不使用享元模式的多。时间上多1秒,内存上差别比较微小,大约3K

创建对象             

最大内存 = 1888485376    最大内存 = 1888485376

已分配内存 = 566231040 【540M】  已分配内存 = 209715200【200M】

已分配内存中的剩余空间 = 285112856  已分配内存中的剩余空间 = 47670392

已用内存 = 281118184 【268M】  已用内存 = 162044808【154M】

时间 = 1550287889171    时间 = 1550297831983

在创建对象的时候,享元模式使用的内存少和创建对象使用的时间少

对象调用display()方法

最大内存 = 1888485376   最大内存 = 1888485376

已分配内存 = 566231040   已分配内存 = 209715200

已分配内存中的剩余空间 = 285112856   已分配内存中的剩余空间 = 47670392

已用内存 = 281118184     已用内存 = 162044808

时间 = 1550287889181     时间 = 1550297832126

总结:

从上面的数据分析可以得出,使用享元模式初始化的时间较长,但在对象创建时间和内存的消耗都比较少。所以在使用享元模式时,评估使用享元模式节省的内存与多消耗的时间,是否带来了以时间换空间的效果。从上面的例子中,使用享元模式确实达到了以时间换空间的效果。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值