多线程中未知进程的高CPU使用率

时间:2017-04-26 06:34:30

标签: multithreading scala jvm nlp large-text

我们的服务器内存为35GB,英特尔®至强(R)E5-1620 0 @ 3.60GHz×8 CPU。我正在运行一个用akka actor设计并用scala编写的多线程程序。在该计划中,有4个参与者负责任务:

1)使用Scala的BufferedSource和迭代器

从文件中进行延迟读取

2)标记句子,

3)计算给定窗口大小的单个和双字母单词的频率,并将它们放入一个映射中(单个单词的一个映射[String,Int],一个用于元组单词[WordTuple,Int],

4)将返回的hasmaps合并到一个hashmap中,当所有行从文件读取并将它们写入文件时。

我的自定义jvm设置如下:

-Xms34g

-Xmx34g

-XX:ReservedCodeCacheSize =240米

-XX:+ UseParallelGC

-XX:ParallelGCThreads = 4

-XX:新尺寸=12克

-XX:SoftRefLRUPolicyMSPerMB = 50

-ea

-Dsun.io.useCanonCaches =假

-Djava.net.preferIPv4Stack =真

-XX:+ HeapDumpOnOutOfMemoryError

-XX:-OmitStackTraceInFastThrow

-Dawt.useSystemAAFontSettings = LCD

-Dsun.java2d.renderer = sun.java2d.marlin.MarlinRenderingEngine

-verbose:GC

-XX:+ PrintGCDetails

-Xloggc:gc.log

我的application.conf如下:

systemParameters {
  linesPerActor = 5
  windowSize = 6
  threadPoolSize = 5
}


akka.actor.deployment {

  /wordTokenizerRouter {
    router = round-robin-pool
    nr-of-instances = 5
  }

  /frequencyCalculatorRouter {
    router = round-robin-pool
    nr-of-instances = 5
  }
}

问题:

我正在处理大小为15gb的文本文件。程序开始工作,过了一会儿,说2个小时,那些标记,计算操作几乎不起作用,没有操作可以执行。耗时300毫秒的操作开始耗时100000秒。但是所有处理器的CPU使用率都是%100。我已经尝试使用jvisualvm来驱动它,但是采样器没有使用这种高CPU使用率,所以我无法确定哪个进程正在使cpu%100。我从jvisualvm检查gc活动,大多数时候它使用的是%10 cpu。那么,我的程序可能存在什么问题,哪个进程可能使用了所有的cpu?

这里有一些来自jvisualvm的截图,当程序中的操作停止但cpu使用率是%100时:

Garbage collector status screenshot

Overall status screenshot

希望我解释清楚。提前感谢您的回答。

1 个答案:

答案 0 :(得分:0)

我会研究几个方面。

  1. 你的堆看起来很满,包括老一代。另一个提示:在8小时20分钟的运行时间内,您的应用程序在olg generation GC中花费了5小时45分钟。当你的堆满了,它会一个接一个地触发完整的GC。 使用Parallel GC,这将在完整GC期间使用所有核心。 看看你的gc.log,看看完整的GC被触发了多少次。
  2. 在CPU加载期间,创建一些线程转储。你可以使用VisualVM'或者`jstack'命令。在Visual VM中,它位于'线程'选项卡,'线程转储'。查看堆栈转储并查找' Runnable'线程,不在某些阻塞/ IO API。看看他们在做什么。
  3. 如果花时间在垃圾收集中。我会采取堆转储并分析所持有的内存。您也可以在Monitor选项卡中的VisualVm中进行堆转储,并在那里进行粗略分析。