Android垃圾收集器慢下来

时间:2011-07-19 04:30:59

标签: java android

我是一名经验丰富的程序员,在java中并不是那么多。为了帮助学习Java / Android,我开始研究一个世界构建器应用程序,它需要2-7个字符,并找到所有常见的单词。目前,我有大约10,000个单词,分为26个.txt文件,这些文件是根据用户输入的字符加载的。它共有~10kb的数据。

逻辑是容易的部分,但现在,GC似乎正在减慢一切,我正在努力寻找优化方法,因为我缺乏Java经验。下面是代码,我几乎是消极的,GC一直在运行。我想指出2-4个字符,下面的代码运行得非常快。比这更大的东西变得非常慢。

public void readFile() throws IOException, NotFoundException
{       
    String dictionaryLine = new String(); //Current string from the .txt file
    String currentString =  new String(); //Current scrambled string
    String comboStr =  new String();      //Current combo string

    int inputLength = myText.getText().length(); // lenth of the user input

    //Loop through every "letter" dictionary
    for(int z = 0; z < neededFiles.length - 1; z++)
    {
        if(neededFiles[z] == null)              
            break;

        InputStream input = neededFiles[z];
        InputStreamReader inputReader = new InputStreamReader(input);
        BufferedReader reader = new BufferedReader(inputReader, inputLength);

        //Loop through every line in the dictionary
        while((dictionaryLine = reader.readLine()) != null)
        {   
            Log.i(TAG, "dictionary: " + dictionaryLine);

            //For every scrambled string...
            for(int i = 0; i < scrambled.size(); i++)
            {

                currentString = scrambled.get(i).toString();

                //Generate all possible combos from the scrambled string and populate 'combos'
                generate(currentString);

                //...lets find every possible combo from that current scramble
                for(int j = 0; j < combos.size(); j++)
                {
                    try 
                    {  
                        comboStr = combos.get(j).toString();

                        //If the input length is less than the current line, don't even compare
                        if(comboStr.length() < dictionaryLine.length() || comboStr.length() > dictionaryLine.length())
                            break;

                        //Add our match
                        if(dictionaryLine.equalsIgnoreCase(comboStr))
                        {
                            output.add(comboStr);
                            break;
                        }
                    }
                    catch(Exception error)
                    {
                        Log.d(TAG, error.getMessage());
                    }
                }
                combos.clear();
            }
        }           
    }
}

为了帮助澄清此代码,请生成以下许多行:

GC_FOR_MALLOC freed 14000 objects / 510000 byes in 100ms

我感谢您提供的任何帮助,即使它只是Java最佳实践。

2 个答案:

答案 0 :(得分:0)

通常,您可以通过创建和丢失较少的对象来减少垃圾收集活动。有很多地方可以生成对象:

  1. 您正在阅读的每一行都会产生一个字符串。
  2. 字符串是不可变的,因此可能会在generate()函数中生成更多对象。
  3. 如果要处理大量字符串,请考虑使用StringBuilder,它是一个可变字符串构建器,可以减少垃圾。

    但是,垃圾收集的100毫秒还不错,尤其是在手机设备上。

答案 1 :(得分:0)

基本上,你是一个糟糕的方式,因为对于每个字典单词,你为所有乱码字符串生成所有可能的组合,yikes!如果你有足够的内存,只需为所有单词生成一次所有组合,并将每个单词与每个字典值进行比较。

但是,必须假设没有足够的内存,在这种情况下,这将变得更加复杂。你可以做的是使用char []产生一种争夺可能性,测试它,重新排列缓冲区中的字符,测试,重复等,直到所有可能性都用完为止。