改善每项表现

时间:2015-03-05 14:15:20

标签: java android arrays foreach

我的Android应用程序中不断运行以下CountDownTimer

CountDownTimer timer_status;
timer_status = new CountDownTimer(1000,1000) {

    List<Integer> lst = new ArrayList<Integer>();
    int k=0;
    @Override
    public void onTick(long millisUntilFinished) {


        String S = "";
        k=0;
        byte[] writeBuffer = new byte[8];

        for (int value : lst) {

            if(k==8) {
                k=0;
                S="";
             }

            S = S + String.format("%02x ", value).toUpperCase();
            writeBuffer[k] = (byte) value;
            k++;

        }

        editSent.setText(S);                            
}

每个循环,应用程序从byte[]整数创建一个新的List缓冲区。

它工作正常,但在LogCat中生成GC_FOR_ALLOC

03-05 11:12:41.330: D/dalvikvm(21178): GC_FOR_ALLOC freed 511K, 19% free 4662K/5720K, paused 14ms, total 14ms
03-05 11:12:42.250: D/dalvikvm(21178): GC_FOR_ALLOC freed 511K, 19% free 4662K/5720K, paused 15ms, total 15ms
  

GC_FOR_ALLOC被触发,因为堆上没有足够的内存来执行分配。在创建新对象时可能会触发。

如何改进此foreach循环,在堆上留下足够的内存?

2 个答案:

答案 0 :(得分:1)

 StringBuilder sb = new StringBuilder(); 
 k=0; 
 byte[] writeBuffer = new byte[8];

 for (int value : lst) { 
 if(k==8) { k=0; sb.setLength(0); 
 } 
 sb.append(String.format("%02x ", value)); 

 writeBuffer[k] = (byte) value; k++; 
 }

 editSent.setText(sb.toString().toUpperCase());

StringBuilder之外,我想指出,正常for的效果优于Android中的foreach,因为foreach循环会创建一个隐藏的Iterator对象。因此,请避免在Android中使用性能关键代码中的for-each。

另外,如果可能的话,使用普通Array作为原始类型而不是ArrayList,因为在每个循环中都会发生自动装箱/拆箱,这会影响您的性能。

答案 1 :(得分:-1)

使用StringBuilder是一回事(见注释)。

您还可以避免局部变量SwriteBuffer,而是使用类变量,这有效地重复使用每个调用,而不是将它们传递给垃圾回收。