编程语言
首页 > 编程语言> > Java线程在处理结束时变慢

Java线程在处理结束时变慢

作者:互联网

我有一个Java程序,它接收一个包含文本文件列表的文本文件,并分别处理每一行.为了加快处理速度,我使用带有24个线程的FixedThreadPool的ExecutorService来使用线程.该机器有24个内核和48GB内存.

我正在处理的文本文件有250万行.我发现,对于前230万行左右,在CPU利用率很高的情况下运行良好.然而,超过某些点(大约在2.3行),性能退化,只使用了一个CPU,我的程序几乎停止了.

我调查了很多原因,确保关闭所有文件句柄,并增加提供给JVM的内存量.但是,无论我改变什么,性能总是会降低到最后.我甚至尝试过包含更少行的文本文件,并且在处理文件结束时性能再次下降.

除了标准的Java并发库之外,代码还使用Lucene库进行文本处理和分析.

当我没有线程化这个代码时,性能是不变的,并且不会在最后退化.我知道这是一个黑暗的镜头,很难描述发生了什么,但我想我会看到是否有人有任何想法可能会导致这种性能退化到底.

编辑

在我收到的评论之后,我已经粘贴了一个堆栈跟踪here.正如您所看到的,它似乎没有任何线程阻塞.此外,在分析时,当事情变慢时,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();

解决方法:

这听起来很像垃圾收集/内存问题.

当垃圾收集运行时,它会暂停所有线程,以便GC线程可以执行其“可收集的垃圾”分析,而不会对其进行任何更改.当GC运行时,您将看到100%的正好1个线程,其他线程将停留在0%.

我会考虑添加一些Runtime.freeMemory()调用(或使用分析器)来查看在GC期间是否“发生停顿”.

我还尝试在你的文件的前10k行运行你的程序,看看是否有效.

我还要看看你的程序是否在使用StringBuilders时构建了太多的中间字符串.

听起来像你需要描述你的内存使用情况.

标签:java,multithreading,lucene,java-util-concurrent
来源: https://codeday.me/bug/20190703/1370254.html