Android - 太多新的String会导致非常慢的GC信息

时间:2017-01-19 06:56:00

标签: java android

每台机器都有一个myFile可供阅读。 myFile中有大量元素需要阅读。每个元素有256个字节,因此我将recData声明为256个字节。在while (bis.read(recData, 0, SIZE_OF_DB_Record) != -1)中,每个循环从myFile读取一个元素(256字节)到recData并解析信息并存储到tcrDbRecord变量中。信息可能会被解析为String,int或long。因此,我还使用ntoh_4bytesntoh_8bytes来解析int和long,因为从网络接收myFile

关键在于它可以正常工作,但成本超长。我发现原因可能是我使用new String()次数太多了。然后,我做了一个实验。如果我删除new String()中的所有while loop代码,它的速度非常快。如果我在new String()中添加一个while loop代码,则显然会变慢。我是客人,问题是由于使用了太多new String()造成的。此外,我还获得了很多这种GC信息

Background sticky concurrent mark sweep GC freed 390820(8MB)
AllocSpace objects, 0(0B) LOS objects, 25% free, 23MB/31MB, paused 519us total 100.362ms. 

但是,我需要通过ASCII码解析这些信息。请帮我解决。

File file;
BufferedInputStream bis;
byte[] recData = new byte[256];
byte[] tmpRecDataStr = new byte[256];            
byte[] tmpRecDataLong = new byte[8];
byte[] tmpRecDataInt = new byte[4];
TCR_DB_Record tcrDbRecord = new TCR_DB_Record();

for (int i = 0; i < numMachine; i++) {
    try {
        file = new File(LoginActivity.dataDir + "/" + i, "myFile");
        bis = new BufferedInputStream(new FileInputStream(file));
        while (bis.read(recData, 0, 256) != -1) {

            //get date
            System.arraycopy(recData, 0, tmpRecDataLong, 0, 4);
            tcrDbRecord.date = ntoh_8bytes(tmpRecDataLong);

            //get time
            System.arraycopy(recData, 4, tmpRecDataLong, 0, 4);
            tcrDbRecord.time = ntoh_8bytes(tmpRecDataLong);

            //get channel
            System.arraycopy(recData, 8, tmpRecDataInt, 0, 2);
            tcrDbRecord.chanNo = ntoh_4bytes(tmpRecDataInt);

            //get file path
            System.arraycopy(recData, 10, tmpRecDataStr, 0, 16);
            tcrDbRecord.filePath = new String(tmpRecDataStr, 0, 16, "US-ASCII");
            tcrDbRecord.filePath = tcrDbRecord.filePath.replaceAll("\\u0000", "");

            //get file name
            System.arraycopy(recData, 26, tmpRecDataStr, 0, 14);
            tcrDbRecord.fileName = new String(tmpRecDataStr, 0, 14, "US-ASCII");
            tcrDbRecord.fileName = tcrDbRecord.fileName.replaceAll("\\u0000", "");

            //get file size in byte
            System.arraycopy(recData, 64, tmpRecDataLong, 0, 4);
            tcrDbRecord.fileSize = ntoh_8bytes(tmpRecDataLong);

            //get length of the record in second
            System.arraycopy(recData, 68, tmpRecDataLong, 0, 4);
            tcrDbRecord.second = ntoh_8bytes(tmpRecDataLong);

            //get value
            System.arraycopy(recData, 76, tmpRecDataLong, 0, 4);
            tcrDbRecord.value = ntoh_8bytes(tmpRecDataLong);

            //get case id
            System.arraycopy(recData, 80, tmpRecDataStr, 0, 16);
            tcrDbRecord.caseID = new String(tmpRecDataStr, 0, 16, "US-ASCII");
            tcrDbRecord.caseID = tcrDbRecord.caseID.replaceAll("\\u0000", "");

            //get comment
            System.arraycopy(recData, 96, tmpRecDataStr, 0, 16);
            tcrDbRecord.comment = new String(tmpRecDataStr, 0, 16, "US-ASCII");
            tcrDbRecord.comment = tcrDbRecord.comment.replaceAll("\\u0000", "");

            //get extension
            System.arraycopy(recData, 112, tmpRecDataStr, 0, 24);
            tcrDbRecord.ext = new String(tmpRecDataStr, 0, 24, "US-ASCII");
            tcrDbRecord.ext = tcrDbRecord.ext.replaceAll("\\u0000", "");

            //get agent name
            System.arraycopy(recData, 136, tmpRecDataStr, 0, 32);
            tcrDbRecord.name = new String(tmpRecDataStr, 0, 32, "US-ASCII");
            tcrDbRecord.name = tcrDbRecord.name.replaceAll("\\u0000", "");

            //get agent id
            System.arraycopy(recData, 168, tmpRecDataStr, 0, 24);
            tcrDbRecord.id = new String(tmpRecDataStr, 0, 24, "US-ASCII");
            tcrDbRecord.id = tcrDbRecord.id.replaceAll("\\u0000", "");

            //get department
            System.arraycopy(recData, 192, tmpRecDataStr, 0, 32);
            tcrDbRecord.dep = new String(tmpRecDataStr, 0, 32, "US-ASCII");
            tcrDbRecord.dep = tcrDbRecord.dep.replaceAll("\\u0000", "");

            //get group
            System.arraycopy(recData, 224, tmpRecDataStr, 0, 32);
            tcrDbRecord.group = new String(tmpRecDataStr, 0, 32, "US-ASCII");
            tcrDbRecord.group = tcrDbRecord.group.replaceAll("\\u0000", "");
        }

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

ntoh_4bytesntoh_8bytes的代码如下所示,但我认为无关紧要。

int ntoh_4bytes(byte[] b)
{
    return   b[0] & 0xFF |
            (b[1] & 0xFF) << 8 |
            (b[2] & 0xFF) << 16 |
            (b[3] & 0xFF) << 24;
}


long ntoh_8bytes(byte[] b)
{
    return   b[0] & 0xFF |
            (b[1] & 0xFF) << 8 |
            (b[2] & 0xFF) << 16 |
            (b[3] & 0xFF) << 24 |
            (b[4] & 0xFF) << 32 |
            (b[5] & 0xFF) << 40 |
            (b[6] & 0xFF) << 48 |
            (b[7] & 0xFF) << 56;
}

0 个答案:

没有答案