2017-04-26 85 views
2

我们拥有35GB内存和Intel®Xeon®E5-1620 0 @ 3.60GHz×8 CPU的服务器。我正在运行一个用akka演员设计的多线程程序,并用scala编写。在节目中,有4个行动者的任务:多线程中未知进程的高CPU使用率

1)懒惰从与Scala的BufferedSource文件和迭代器读取,

2)标记化的句子,

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

4)将返回的hasmaps合并到一个hashmap中,文件并将它们写入文件。

我的自定义JVM设置如下:

-Xms34g

-Xmx34g

-XX:ReservedCodeCacheSize =240米

-XX:+ UseParallelGC

-XX: ParallelGCThreads = 4

-XX:NewSize = 12g

-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

希望我解释清楚。预先感谢您的答案。

回答

0

我想看看几个区域。

  1. 你的堆看起来很饱满,包括老一代。另一个提示:在8小时20分钟的运行时间中,您的应用程序在olg generation GC中花费了5小时45分钟。当你堆满了时,它会一个接一个地触发完整的GC。 使用并行GC,将在完整GC期间使用所有核心。 看看你是gc.log,看看完整GC触发了多少次。
  2. 在CPU加载期间,创建一些线程转储。您可以使用VisualVM'或'jstack'命令。在Visual VM中,它位于'线程'选项卡上,'线程转储'。查看堆栈转储并查找'Runnable'线程,这些线程不在某些阻塞/ IO API中。看看他们在做什么。

如果花费时间在垃圾收集。我会采取堆转储并分析持有的内存。您也可以在Monitor选项卡的VisualVm中进行堆转储,并在那里进行粗略分析。

+0

正如我现在所观察到的,随着时间的流逝,垃圾回收的频率在不断增加,因此运行应用程序的5秒钟之后会有10秒的垃圾回收。随着时间的流逝,这段时间越来越狭窄。现在,我观察到更具体的问题,垃圾收集器运行不能清理整个空间,它只是清理一些未使用的引用,并且应用堆再次变满。这里有一个截图的证明:http://imgur.com/0NbZelt和另一个gc使用高cpu:http://imgur.com/a/YSrsw所以,应用程序进程正在工作较少。 – katilsperm

+0

垃圾收集的原因是什么,在运行时无法清除所有未使用的引用? – katilsperm

+0

你的应用程序保存对象的引用,所以GC不能收集是。 如果你确实需要这些参考资料,请参阅这些参考资料。 像,采取堆转储。那么堆中有什么实例。使用“查找根”来找出引用是如何保持活着的。 – Gamlor