Потоки Java замедляются к концу обработки

У меня есть Java-программа, которая принимает текстовый файл, содержащий список текстовых файлов, и обрабатывает каждую строку отдельно. Чтобы ускорить обработку, я использую потоки, используя ExecutorService с FixedThreadPool с 24 потоками. Машина имеет 24 ядра и 48 ГБ оперативной памяти.

Текстовый файл, который ям обработки имеет 2,5 миллиона строк. Я считаю, что для первых 2,3 миллиона строк или около того все работает очень хорошо с высокой загрузкой процессора. Тем не менее, в какой-то момент (около 2,3 строки) производительность снижается, когда используется только один процессор, и моя программа практически остановилась.

Мы исследовали ряд причин, убедились, что все мои файловые дескрипторы закрыты, и увеличили объем памяти, предоставляемой JVM. Однако, независимо от того, что я изменяю, производительность всегда падает к концу. Я'Мы даже пробовали текстовые файлы, содержащие меньше строк, и снова производительность снижается к концу обработки файла.

В дополнение к стандартным библиотекам параллелизма Java, код также использует библиотеки Lucene для обработки и анализа текста.

Когда я нет нить этот код, производительность постоянна и невырождается ближе к концу. Я знаю, что это выстрел в темноте, и этоТрудно описать, что происходит, но я подумал, что я просто посмотрю, есть ли у кого-нибудь какие-либо идеи относительно того, что может привести к ухудшению производительности к концу.

редактировать

После комментариев яя получил, явставил трассировку стекаВот, Как вы можете видеть, это неПохоже, что любой из потоков блокирует. Кроме того, при профилировании GC не был на 100%, когда все замедлилось. Фактически загрузка ЦП и ГХ составляла в большинстве случаев 0%, при этом ЦП время от времени включал обработку нескольких файлов, а затем снова останавливался.

Код для выполнения потоков

 BufferedReader read = new BufferedReader(new FileReader(inputFile));
 ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
 String line;
 while ((line = read.readLine()) != null) { //index each line
     Runnable worker = new CharikarHashThreader(line, bits, minTokens);
     executor.execute(worker);
 }
 read.close();

Ответы на вопрос(2)

Ваш ответ на вопрос