5

我正在 Intellij Idea 中运行一些 CPU 密集型 Clojure 代码(我认为这并不重要——它似乎只是产生了一个进程)。根据 htop 和 top 的说法,它在我的笔记本电脑上使用了所有 4 个内核(嗯,2 + 超线程)。尽管我在代码中没有任何明确的并行性。

更详细一点:top 显示了一个 CPU 使用率约为 380% 的单个进程,而 htop 显示了一个“父”进程,然后是 4 个“子”进程,每个进程有 1/4 的时间和 100% 的 CPU。

这是正常的吗?或者这是否意味着我在某个地方遇到了一些非常错误的事情?该代码涉及许多惰性序列,但其核心修改了可变数据结构(可变的 - 不是 Clojure 数据结构 - 累积结果的哈希)。 我没有使用任何明确的并行性。

在 JCA/JCE(加密库)中可能花费了大量时间(我没有分析过) - 我在 CTR 模式下使用多个 AES 密码,每个密码都作为安全随机字节流(此处的代码),实现为惰性序列。也许这是并行化的?

更多随机想法:这可能与 IO 有关吗?我在一个加密的 SSD 上运行,这个程序正在处理来自磁盘的数据,所以进行了大量的读取。但是 htop 将系统时间显示为红色,而这些是绿色的。

抱歉问了这么模糊的问题。如果需要,我可以发布更多信息。这是 64 位 Linux (JDK 1.7.0_05) 上的 Clojure 1.4。正在执行的代码在这里,但它非常混乱(更抱歉)并且分布在各种文件中(大部分 CPU 时间都花在了nearest-in-dump那里的代码中)。注意 - 请不要浪费时间尝试运行代码来重现,因为它期望预先存在的数据转储在磁盘上(不在 git 中)。

调试器在调试器中运行(谢谢,AM)显示四个线程(如果我正确理解调试器),但只有一个正在执行程序。它们被标记为终结器、主(程序)、引用处理程序和信号调度程序。Finalizer + ref handler 处于等待状态;信号调度程序没有可用的帧。我暂时认为这意味着并行性处于较低水平,也许在加密实现中?

啊哈,我认为它是并行 GC(Java 现在有一个并发收集器)。开始时,当实际进程暂停时,CPU 使用率会大幅上升(它会打印出一个常规的滴答声)。而且由于它正在处理大量数据,因此会生成许多短期对象(通过使用 -XX:+UseSerialGC 确认,这将 CPU 使用率降低到 100%)

4

1 回答 1

4

好的,我觉得发布这个有点愚蠢,因为它现在看起来很明显,但它似乎是并行 GC。我正在处理大量数据(从 SSD 中吸入)并生成大量短期对象。看来 JVM 有并行 GC。见http://blog.ragozin.info/2011/12/garbage-collection-in-hotspot-jvm.html

这也可能是问题的征兆 - java GC 发生了什么?PermGen 空间已满?- 我明天会调查(我没有提到它 - 尽管回想起来我应该有 - 但这是内存不足的临界点)。

更新:使用 -XX:+UseSerialGC 运行可将总 CPU 使用率降低到 100%(即 1 个核心)。但我并不是说上面的两种解释是排他性的,只是通过更好的配置和/或代码我可以减少 GC 的数量。

于 2012-07-07T02:32:34.913 回答