2016-09-26 2 views
-2

Я написали код. Проблема, с которой я столкнулась, заключается в том, что когда «j» цикла for превышает 1000, я начинаю получать ошибку «превышение верхнего предела GC». Если я увеличиваю выделенную память до 4 ГБ, я могу повторить до 2000, после чего возникает одна и та же проблема. Я хочу сохранить этот вариант увеличения памяти в крайнем случае и хочу попытаться масштабировать мой код. Компилятор выделяет проблему с операторами, в которых я разместил стрелку. Может кто-нибудь, пожалуйста, назовите меня, что может быть возможной ошибкой здесь. я уже посетил этот вопрос Error java.lang.OutOfMemoryError: GC overhead limit exceededВерхний предел GC превышен в коде

 for (int j=1; j<=num_doc; j++) { 
     List<Integer> list1 = new ArrayList<Integer>(Collections.nCopies(129039, 0)); 
     BufferedReader fl = new BufferedReader(new FileReader(dataFolder+"file"+ " ("+j+")"+".int")); 
     String line1; 

     while((line1=fl.readLine()) != null) { 

      String[] arr=line1.split(" ");//<--------------------- 
      line1=""; 
      int k = Integer.parseInt(arr[0]); 
      Arrays.fill(arr, ""); 
      numb=numb+1; 
      int temp=(list1.get(k))+1; 
      list1.set(k, temp); 
     } 
     F_d.add(numb); 
     numb=0; 
     fl.close(); 
     ls2d.add(new ArrayList<Integer>(list1));//<--------------------- 
     list1.clear(); 
    } 
+0

ли вам ясный 'ls2d' где-то в вашем коде? –

+0

Да ls2d используется. Я вставил только ту часть кода, которую выделяет компилятор. – Shahzaib

+0

'list1' уже довольно большой, поэтому, если вы потратите свое время, чтобы добавить его в' ls2d', не очистив его, он быстро займет много памяти, что приведет к OOME –

ответ

0

Две вещи могут быть немедленно оптимизированы для меньше требований к памяти:

 // we don't need all the fragments, taking only the first is fine 
     String firstElem=line1.substring(0, line1.indexOf(" ")); 
     line1=null;// let GC collect this at its convenience 
     int k = Integer.parseInt(firstElem); 

затем

// Don't add the copy, add list1 itself 
    // You are initing list1 in the beginning of the for cycle anyway 
    // and until then nothing happens. 
    ls2d.add(list1);//<--------------------- 
    // list1.clear(); -- since we added list1, we don't clear it anymore 
+0

Я внес эти изменения, и ошибка там осталась – Shahzaib

+0

@Shahzaib - изменились ли строки, в которых произошло OOM? –

+0

Да, теперь это ошибка пространства кучи Java, появляющаяся в ls2d.add (list1) кода, который я вставил – Shahzaib

0

Вот несколько идей, чтобы уменьшить потребление памяти - и время выполнения возможно.

  • использовать массив вместо ArrayList - Вы, кажется, не использовать ArrayList определенные функциональные возможности, так массив будет более компактным и проще работать с
  • СКАЖИТЕ раскола, чтобы просто прочитать первое поле строки

Обратите внимание, что я удалил весь код, предназначенный для принуждения сборщика мусора к очистке, я не думаю, что это помогает в этом случае.


for (int j=1; j<=num_doc; j++) { 
    int[] list1 = new int[129039]; 

    BufferedReader fl = new BufferedReader(new FileReader(dataFolder+"file"+ " ("+j+")"+".int")); 
    String line1; 

    while((line1=fl.readLine()) != null) { 
     String[] arr=line1.split(" ",2); // Just read first field - see String Javadoc 
     int k = Integer.parseInt(arr[0]); 
     list[k]=list[k]+1; 
     numb=numb+1; 
    } 
    F_d.add(numb); 
    numb=0; 
    fl.close(); 
    ls2d.add(list1);// you'll obviously need to change ls2d's type, or reconvert using Arrays.asList 
}