我有一个 Java 程序,它接收一个包含文本文件列表的文本文件,并分别处理每一行。为了加快处理速度,我使用带有 24 个线程的 FixedThreadPool 的 ExecutorService 线程。该机器有 24 个内核和 48GB 的 RAM。
我正在处理的文本文件有 250 万行。我发现对于前 230 万行左右的内容,在 CPU 利用率很高的情况下运行得非常好。然而,超过某个点(大约 2.3 行),性能下降,只使用一个 CPU,我的程序几乎停止运行。
我调查了许多原因,确保我的所有文件句柄都已关闭,并增加了提供给 JVM 的内存量。但是,无论我改变什么,性能总是会在最后下降。我什至尝试过包含更少行的文本文件,并且在处理文件结束时性能再次下降。
除了标准的 Java 并发库之外,代码还使用 Lucene 库进行文本处理和分析。
当我不线程化这段代码时,性能是恒定的,并且不会在最后退化。我知道这是在黑暗中拍摄,很难描述发生了什么,但我想我想看看是否有人对最终导致性能退化的原因有任何想法。
编辑
在收到评论后,我在此处粘贴了堆栈跟踪。如您所见,似乎没有任何线程正在阻塞。此外,在进行分析时,当事情变慢时,GC 并没有达到 100%。事实上,大部分时间 CPU 和 GC 利用率都为 0%,CPU 偶尔会飙升以处理一些文件,然后再次停止。
执行线程的代码
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();