Android开发经验小节2:循环利用你的小对象

在上一篇中提出的原则都是为了避免创建不必要的对象。对于占用资源较多的对象,可以在程序初始化中创建,并一直使用,比如图片资源。对于一些不变的对象,如字符串、常数,可以采用静态常量的办法。但我们开发过程中还会遇到另一种情况,有些对象虽然占用资源少,但使用频率高(比如记录屏幕点位置坐标的对象),对于这种情况应该如何处理呢?

这个问题其实比较复杂,要具体情况具体分析,但还是有一些规律可循。

原则1:建立对象池循环利用小对象

例如如下类:

 

   
   
1 public class TestPoint 2 { 3 public int mX; 4 public int mY; 5 public TestPoint( int x, int y) 6 { 7 set(x,y); 8 } 9 10 public void set( int x, int y) 11 { 12 mX = x; 13 mY = y; 14 } 15 }

 

使用时:

 

 

   
   
public void test() { for ( int i = 0 ;i < 10000 ;i ++ ) { TestPoint p = new TestPoint(i,i); 。。。 } }

 

通过分析,以上代码会创建10000个TestPoint新对象,这当然是不合理的,可以用如下办法优化:

 

 

   
   
1 public class TestPoint 2 { 3 public int mX; 4 public int mY; 5 public TestPoint( int x, int y) 6 { 7 set(x,y); 8 } 9 10 public void set( int x, int y) 11 { 12 mX = x; 13 mY = y; 14 } 15 16 17 /** 18 * 对象池 19 */ 20 private static ArrayList < TestPoint > sPoints = null ; 21 22 /** 23 * 从对象池中获取一个对象,如果空池则创建新对象,并初始化 24 * @param x 横坐标 25 * @param y 纵坐标 26 * @return 对象 27 */ 28 public static TestPoint popPoint( int x, int y) 29 { 30 TestPoint p = null ; 31 if (sPoints != null && sPoints.size() > 0 ) 32 { 33 p = sPoints.remove( 0 ); 34 p.set(x, y); 35 } 36 else 37 { 38 p = new TestPoint(x,y); 39 } 40 return p; 41 } 42 43 /** 44 * 向对象池归还一个对象,如果空池则先创建池 45 * @param p 要归还的对象 46 */ 47 public static void pushPoint(TestPoint p) 48 { 49 if (sPoints == null ) 50 { 51 sPoints = new ArrayList < TestPoint > (); 52 } 53 54 sPoints.add(p); 55 } 56 57 }

 

在使用时:

 

 

   
   
public void test2() { for ( int i = 0 ;i < 10000 ;i ++ ) { TestPoint p = TestPoint.popPoint(i, i); // 获取对象 。。。 TestPoint.pushPoint(p); // 归还对象 } }

 

这样,由于使用过的对象归还给了对象池,当需要时优先从池中获取对象,实际创建对象的次数将明显下降。

 

原则2:给你的对象池设一个上限

前面的代码也有局限性,例如如果程序的逻辑造成其对象获取峰值较高,池中的对象将或很多,当程序对象获取需求减少时,池中的对象就成为了占用内存的累赘了。一个可行的办法是,为对象池中对象数设定一个上限,当归还对象时发现池中对象已经达到这个上限了,就不再将其放入池中。只要这个上限设定合理,池内存占用和GC释放内存压力可以找到一个较好的平衡点。

原则3:保护好你的对象池

这里需要强调的是,对于多线程共用的对象池,应该对所有访问对象池的静态方法进行严格的线程保护,因为ArrayList的操作还是比较费时且多线程共同对其访问是是有线程冲突的。

 

小结:

对象池的使用可以对频繁使用的小对象进行有效的循环利用,如果运用合理,可以极大地提升程序的运行效率和降低程序的资源占用。但请相信,没有普遍适用的最优方案,必须具体问题具体分析。

 

作者:汪峰 www.otlive.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值