Android大批量对象分配效率

时间:2015-08-14 02:32:34

标签: java android performance garbage-collection heap-memory

我正在寻找一些Android / Java建议。我没有经验丰富的GC。

我写的应用程序在开头读取一大堆文本数据,然后将其解析为~40000个独立(相对较小)的对象。由于其他功能,我无法将它们缩减为原语,这会产生相当慢的加载时间(~6秒)。我认为我已经专门针对对象分配进行了搜索,但我现在却不知道如何提高效率。

以下是执行慢工作的代码:

protected Void doInBackground(ArrayList<Song>... lists) {

    String[] vals;
    long startT = 0, readT = 0, splitT = 0, songsT = 0, doneT;

    try {
        InputStream is = mContext.getResources().openRawResource(fid);
        int dataLength = is.available();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        int dataRead, chunkRead;
        char[] buf = new char[dataLength];

        dataRead = 0;
        startT = System.nanoTime();
        while((chunkRead = reader.read(buf, dataRead, Math.min(4096, dataLength - dataRead))) > 0) {
            dataRead += chunkRead;
            publishProgress((int)(dataRead*6000 / (float)dataLength));
        }
        publishProgress((int)(dataRead*6000 / (float)dataLength));
        reader.close();
        readT = System.nanoTime();

        String[] tokens = Pattern.compile("[\n|\r]+").split(new String(buf));
        splitT = System.nanoTime();
        publishProgress(7000);

        for(String t : tokens) {
            vals = t.split(" - ");
            lists[0].add(new Song(vals[0], vals[1]));
        }
        songsT = System.nanoTime();
        publishProgress(9000);
    } catch (Exception e) {
        Log.e(e.toString(), e.getMessage());
        for (int i = 0, len = e.getStackTrace().length; i < len; ++i) {
            Log.e("StackTrace", e.getStackTrace()[i].toString());
        }
    }

    lists[0].trimToSize();
    doneT = System.nanoTime();
    publishProgress(10000);

    //timing logs
    Log.d("read time", "" + ((readT - startT)/(float)1000000000));
    Log.d("splitting time", "" + ((splitT - readT)/(float)1000000000));
    Log.d("song creation time", "" + ((songsT - splitT)/(float)1000000000));
    Log.d("trim time", "" + ((doneT - songsT)/(float)1000000000));
    Log.d("TOTAL LOAD TIME", "" + ((doneT - startT)/(float)1000000000));
    return null;
}

这里出现的日志让我觉得它是新的对象分配。日志的结尾是上面块中的定时代码的结果。狮子会分享是对象创造。

08-13 21:53:52.470  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 5070K, 40% free 9834K/16168K, paused 86ms, total 86ms
08-13 21:53:52.470  18558-18572/com.example.package I/dalvikvm-heap﹕ Grow heap (frag case) to 12.110MB for 2568400-byte allocation
08-13 21:53:52.540  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed <1K, 24% free 12343K/16168K, paused 66ms, total 67ms
08-13 21:53:52.790  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 313K, 26% free 12078K/16168K, paused 76ms, total 77ms
08-13 21:53:52.790  18558-18572/com.example.package I/dalvikvm-heap﹕ Grow heap (frag case) to 14.301MB for 2568400-byte allocation
08-13 21:53:52.880  18558-18567/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed <1K, 22% free 14586K/18680K, paused 92ms, total 92ms
08-13 21:53:53.380  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 499K, 14% free 16135K/18680K, paused 76ms, total 76ms
08-13 21:53:53.980  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 706K, 7% free 17476K/18680K, paused 105ms, total 106ms
08-13 21:53:54.590  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1552K, 10% free 17775K/19584K, paused 117ms, total 117ms
08-13 21:53:55.270  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1433K, 9% free 18149K/19884K, paused 124ms, total 124ms
08-13 21:53:55.910  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1429K, 9% free 18490K/20260K, paused 129ms, total 129ms
08-13 21:53:56.540  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1337K, 9% free 18900K/20600K, paused 137ms, total 137ms
08-13 21:53:57.190  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1367K, 9% free 19255K/21008K, paused 143ms, total 143ms
08-13 21:53:57.800  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1402K, 9% free 19556K/21364K, paused 146ms, total 146ms
08-13 21:53:58.440  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 1260K, 8% free 19980K/21664K, paused 163ms, total 164ms
08-13 21:53:59.070  18558-18572/com.example.package D/dalvikvm﹕ GC_FOR_ALLOC freed 5158K, 26% free 16486K/22084K, paused 158ms, total 158ms
08-13 21:53:59.080  18558-18572/com.example.package D/read time﹕ 0.23885109
08-13 21:53:59.080  18558-18572/com.example.package D/splitting time﹕ 0.5500893
08-13 21:53:59.080  18558-18572/com.example.package D/song creation time﹕ 5.6512194
08-13 21:53:59.080  18558-18572/com.example.package D/trim time﹕ 0.1600585
08-13 21:53:59.080  18558-18572/com.example.package D/TOTAL LOAD TIME﹕ 6.6002183

我知道应用程序在完成加载后将使用多少内存以及必须分配多少个对象。这些事项中的任何一个都可以减少分配所花费的时间吗?任何指向正确方向的人都会非常感激!

0 个答案:

没有答案