我们有一个计算要求很高的java程序(科学研究),它是单线程设计的。但是,执行时,它会加载超过1个CPU核心(我们注意到它很难 - 集群作业调度程序因为加载的内核多于请求而杀死了我们的程序)。我们在linux(Debian,Ubuntu)和windows(7)上遇到了这种奇怪的现象。
据我所知,java / jvm(垃圾收集器)添加了几个后台线程,所以即使是单线程程序也可以加载多个核心,但我怀疑这些后台进程是否可以加载另一个完整的核心。
我想知道可能导致这种情况的原因。谢谢你的任何提示。请随意询问任何细节,虽然我不能在这里发布代码(首先,它是相当多的代码,其次,它仍在研究中,我还不能发布任何内容)。
答案 0 :(得分:2)
首先,请允许我向你们表示哀悼,让我们在一个有人发现它更能在智力上完成杀死尝试使用多个核心的工作的环境中运行你的程序,而不是限制只使用一个核心的工作。但让我们继续讨论这个问题。
当我暂停一个随机的单线程java程序并查看我的调试器的线程列表时,那里有大约六个线程。这就是JVM的工作原理。垃圾收集至少有一个线程,运行终结器的另一个线程,以及其他各种东西,其中大多数我甚至都不知道它们服务的目的。几十年前,我们失去了准确了解我们机器中发生的事情的游戏。
可能有一些选项可以用来告诉JVM减少对线程的使用,例如在与程序相同的线程中运行垃圾收集,但我不清楚它们,所以你需要查阅它们,坦率地说,我怀疑它会有很大的不同。永远都会有你无法控制的线程。
因此,您似乎必须将自己的工作配置为不使用多个核心。我已经在工作中完成了它,取得了一些成功,但今天是星期六,所以我无法访问我使用的脚本文件,因此我将尝试帮助我记得的任何内容。
您正在寻找的概念是"处理线程关联性"和" NUMA"。
在Windows下,start
命令(内置于cmd.exe中)允许您指定运行进程的逻辑CPU数(换句话说,核心数)。 start /affinity 1 myapp
会运行myapp
将其限制在核心1上。
在Linux下,至少有几个不同的命令允许您在有限的核心子集上启动进程。我所知道的是taskset
而另一个是numactl
。
答案 1 :(得分:1)
你可以玩JVM set of parameters。对于Java 7及更早版本:
对于Java 8,还有其他选项取决于操作系统。您可以在Windows here中看到它们。一些你会发现有用的:
如果您向我们提供其他信息,那么答案将更有帮助和更有用信息