简体   繁体   中英

Android Garbage Collector Slow Down

I'm a semi experienced programmer, just not so much within java. To help learn Java/Android I started working on a world builder application, something that takes 2-7 characters and finds all common words out of that. Currently I have about 10,000 words split between 26.txt files that are loaded based on what characters are inputted from the user. Together it's ~10kb of data.

The logic was the easy part but now, the GC seems to be slowing everything down and I'm struggling to find ways to optimize due to my lack of Java experience. Here is the code below that I'm almost postitive the GC is constantly running on. I'd like to point out with 2-4 characters the code below runs pretty quickly. Anything larger than that gets really slow.

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();
            }
        }           
    }
}

To help clarify this code generates many, many lines of the following:

GC_FOR_MALLOC freed 14000 objects / 510000 byes in 100ms

I appreciate any help you can give, even if it's just Java best practices.

In general, you reduce garbage collection activity by creating and losing less objects. There are a lot of places where objects can be generated:

  1. Each line you are reading produces a String.
  2. Strings are immutable, so likely more objects are being spawned in your generate() function.

If you are dealing with a lot of strings, consider a StringBuilder , which is a mutable string builder which reduces garbage.

However, 100ms for garbage collection is not bad , especially on a phone device.

Basically, you're in a bad way because that for each dictionary word you're generating all possible combinations for all scrambled strings, yikes, If you have enough memory. just generate all the combos for all words once and compare each one to every dictionary value.

However, it must be assumed that there isn't enough memory for this, in which case, this is going to get more complicated. What you can do is use a char[] to produce one scramble possibility, test it, rearrange the characters in the buffer, test, repeat, etc until all possibilities are exhausted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM