高效的对象循环利用

我叫岁寒,一名输入法开发者。下面介绍的是我在输入法开发中使用的一个优化方法——高效的对象循环利用。**(之所以用临岁之寒,是因为有人捷足先登,我更希望你们叫我岁寒,和我的输入法同名)
输入法是常用的软件工具,其对时间响应速度有较高的要求,须要专门优化。与输入法响应速度相关的因素有很多,比如数据库检索、多线程调度和对象管理等方面。本文主要从对象管理方面入手进行优化。


优化思路

我开发的输入法是在安卓平台上运行,使用JAVA语言开发。由于JAVA自带垃圾回收机制,所以很多时候程序员并不需要关心对象如何被回收利用。这种机制有利也有弊,弊在生成和回收对象时程序都要付出时间代价。想要避免这种时间代价,就要绕过回收机制,重复利用已生成的对象,从而减少对象的生成和回收操作。

使用场景

脱离具体场景谈优化都是耍流氓,很少有放之四海而皆准的优化方法,我们先说一说这个优化方法的使用场景。
1.该方法适用于那些方生方死的对象,即我们只是短时间内需要这些对象,很快就弃用,但又需要不断地生成新的对象来使用。 2.我们可以估算出同一时间内有效对象的最大数量。这一点很重要,否则我们并没有办法循环利用对象。
3.多线程竞争烈度较低,或者可以容忍一定的出错概率。

其它需求

根据我项目的需要,我还希望这些对象可以在输入法键盘不使用的时候还给系统,同时,在用户再次调出输入法的时候又可以自动生成,并且使用的时候代码量越少越好。

具体实现

下述的所有代码都在一个叫ObjectBuffer<T>的类里面,先看一下类中的成员。
<pre> <code>
//用于保存所有该类的对象,实现内存的统一回收
static List<ObjectBuffer> AllObjectBuffer = new ArrayList<>();
final int objectNumber;
private final Class objectClass;
private Object[] ObjectArray = null;//保存对象的循环数组
private volatile int index = 0;
</code></pre>
下面是构造器函数和初始化方法。
构造器参数是要复用的类的Class对象和循环数组的长度。
初始化方法则利用反射生成对象备用。使用反射可以节省大量的重复代码。这个类虽然使用了泛型,但在JAVA中并不能使用泛型生成对象,所以此处泛型的作用基本上只是减少了外部执行类型转换的操作而已。
<pre> <code>
public ObjectBuffer(Class objectClass, int number) {
this.objectClass = objectClass;
this.objectNumber = number;
AllObjectBuffer.add(this);
}
</p>
private void initObjectArray() {
index=0;
ObjectArray = new Object[objectNumber];
try {
Constructor constructor = this.objectClass.getConstructor((Class[]) null);
for (int i = 0; i < ObjectArray.length; i++) {
ObjectArray[i] = constructor.newInstance((Object[]) null);
}

    } catch (Exception e) {
        e.printStackTrace();
    }
}

</code></pre>
下面是这个类的核心方法。利用加一和取余让索引循环起来,这个不多说。在本方法中,有两个明显可能出现的异常:空引用和越界,这里使用了异常处理。
当然,对空引用也可以用null条件判断,对越界也可以用边界条件判断。但这样会增加很多代码,而且每一次取对象都要做两次判断,这大多时候都是浪费时间。利用异常可以省下这两个判断,代码也更显洗练。
其中,index被声明为volatile,可使其在多线程中具有更好的可见性,但这并不是绝对线程安全的,在烈度较大的多线程竞争下应该增加同步锁。但在高烈度竞争下的同步操作可能抵冲掉循环复用对象的优化效果,因此要谨慎使用。
<pre><code>
public T Obtain() {
try {
return (T) ObjectArray[index++%objectNumber];
} catch (Exception e) {
initObjectArray();
return Obtain();
}
} </code></pre>

下面的代码用于在用户不使用键盘时释放内存空间。显然,当用户再一次使用输入法,程序试图获取对象时会触发NULL异常,随后调用异常处理,从而实现对象的重新初始化。
可见,异常处理不仅只是作为异常情况的补救措施,也可以作为程序逻辑的一部分。但此做法的前提是在异常发生频率很低的情况下,否则就可能得不偿失。
<pre><code>
public static void ClearAllObjectBuffer() {
for (ObjectBuffer objectBuffer : AllObjectBuffer) {
objectBuffer.clear();
}
}
</p>
private void clear() {
ObjectArray = null;
}
</code></pre>

使用方法

<pre><code>
public class A{
ObjectBuffer buffer =new ObjectBuffer(A.Class,10);
public A Obtain(){
A a =buffer.Obtain();
//这里可以对a做一些清理工作
return a;
}
}
</code></pre>

注意事项

千万不要对需要长期持有的对象使用该方法。切记切记。

写在最后

这个类的代码量其实很少,你如果想要使用这个类,只要把文中的代码整理起来就可以用了。既然代码这么少,我为什么不直接啪代码,而是唧唧歪歪地写这么多东西呢?因为我认为,我是怎么做的不重要,我为什么这么做才是最重要的,所谓道重于术

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,608评论 18 399
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,963评论 25 707
  • 2017一8月31天一星期四一晴 今天早上,吃完饭后一顺急急忙忙地背起书包走了,我往茶几上一看,发现她的...
    一帆风顺平平安安阅读 210评论 0 0
  • 大街上的人总是行色匆匆,忙 你看,他们却步履蹒跚哪 我抬头,反正无人看我 今天的天气很好,真好 微风不躁,清清的 ...
    也去阅读 154评论 0 3
  • ☻今日心晴☻ 周二的深圳,下起了淅沥沥得小雨,貌似有越来越大的趋势。我估摸现在的长沙,早就冷的穿棉衣了吧。 这首歌...
    sunny段晓阅读 115评论 0 0