Превышение лимита накладных расходов GC при чтении текстового файла

Я получаю java.lang.OutOfMemoryError: превышен лимит накладных расходов GC при чтении из текстового файла. Я не уверен, что происходит не так. Я запускаю свою программу в кластере с достаточным объемом памяти. Внешний цикл повторяется 16000 раз и для каждой итерации внешнего цикла внутренний цикл повторяется примерно 300 000 раз. Ошибка возникает, когда код пытается прочитать строку из внутреннего цикла. Любые предложения будут с благодарностью оценены. Ниже приведен мой фрагмент кода:

//Read from the test data output file till not equals null
//Reads a single line at a time from the test data
while((line=br.readLine())!=null)
{
    //Clears the hashmap
    leastFive.clear();

    //Clears the arraylist
    fiveTrainURLs.clear();
    try
    {
        StringTokenizer st=new StringTokenizer(line," ");
        while(st.hasMoreTokens())
        {
            String currentToken=st.nextToken();

            if(currentToken.contains("File"))
            {
                testDataFileNo=st.nextToken();
                String tok="";
                while((tok=st.nextToken())!=null)
                {
                    if (tok==null) break;

                    int topic_no=Integer.parseInt(tok);
                    topic_no=Integer.parseInt(tok);
                    String prob=st.nextToken();

                    //Obtains the double value of the probability
                    double double_prob=Double.parseDouble(prob);
                    p1[topic_no]=double_prob;

                }
                break;
            }
        }
    }
    catch(Exception e)
    {
    }

    //Used to read over all the training data file
    FileReader fr1=new FileReader("/homes/output_train_2000.txt");

    BufferedReader br1=new BufferedReader(fr1);
    String line1="";

    //Reads the training data output file,one row at a time
    //This is the line on which an exception occurs!
    while((line1=br1.readLine())!=null)
    {
        try
        {
            StringTokenizer st=new StringTokenizer(line1," ");

            while(st.hasMoreTokens())
            {
                String currentToken=st.nextToken();

                if(currentToken.contains("File"))
                {
                    trainDataFileNo=st.nextToken();
                    String tok="";
                    while((tok=st.nextToken())!=null)
                    {
                        if(tok==null)
                            break;

                        int topic_no=Integer.parseInt(tok);
                        topic_no=Integer.parseInt(tok);
                        String prob=st.nextToken();

                        double double_prob=Double.parseDouble(prob);

                        //p2 will contain the probability values of each of the topics based on the indices
                        p2[topic_no]=double_prob;

                    }
                    break;
                }
            }
        }
        catch(Exception e)
        {
            double result=klDivergence(p1,p2);

            leastFive.put(trainDataFileNo,result);
        }
    }
}

person collegian    schedule 19.10.2010    source источник


Ответы (1)


16000 * 300000 = 4,8 МЛРД. Если каждый токен занимает всего 6 байт, это само по себе составляет более 24 ГБ. Сборщик мусора будет работать долгое время, когда наконец запустится в gc с 24 ГБ. Кажется, вам нужно разбить это на более мелкие куски. Вы можете ограничить память своего приложения чем-то разумным, например, 1 ГБ, чтобы сборщик мусора запускался раньше и мог что-то сделать за то время, которое ему нужно для выполнения своей работы.

person knunkler    schedule 28.07.2011
comment
Кроме того, я считаю, что Windows игнорирует максимальный размер виртуальной машины более 1,2 ГБ. - person Noah; 29.07.2011