从Java中限制CPU

时间:2012-09-06 14:18:42

标签: java multithreading jvm cpu throttling

我在这个(和其他)论坛上看到了很多同样题目的问题,但似乎没有一个问题可以解决我的问题。就是这个: 我有一个JVM,可以在托管它的机器上占用所有CPU。我想限制它,但我不能依赖任何限制工具/技术外部到Java,因为我不能假设这个Vm将在哪里运行。因此,例如,我无法使用处理器关联,因为如果VM在Mac上运行,则操作系统不会使进程关联性可用。

我需要的是指示在 Java中是否存在以确保线程不占用完整的CPU。

我想直截了当地指出,我不能使用基于交替进程执行和暂停的技术,正如某些论坛所建议的那样,因为线程需要不断生成值。

理想情况下,我想要一些意思,例如,设置一些VM或线程优先级,或以某种方式限制CPU消耗的百分比。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:5)

  

我需要的是指示Java中是否存在手段以确保线程不占用完整的CPU。

除了将应用程序调整为使用更少的CPU之外,我无法在Java中执行此操作。

  • 您可以在计算方法中添加一些Thread.sleep(...);次调用。分析器可以帮助您显示热循环/方法/等..
  • 分叉较少的线程也会影响所使用的CPU。移动到固定大小的线程池或降低池中的线程数。
  • 可能不是CPU是问题而是其他资源。例如,观察您的IO带宽。减慢网络或磁盘读/写可能会使服务器恢复正常运行。

从JVM外部可以使用~unix nice命令来影响正在运行的JVM的优先级,使其不支配系统。这将为CPU提供CPU(如果可用),但会让其他应用程序获得更多的CPU。

答案 1 :(得分:2)

我认为你想要比setting the threads' priorities更可靠的东西?

如果您希望限制执行一些不断生成值的代码,您需要研究线程所做的工作,并在您自己的计时器中进行编码。例如,java.util.Timer允许scheduling execution at a fixed rate

当调度程序没有其他任务可以优先于您的优先级时,任何其他技术仍会消耗尽可能多的CPU(每个线程1个核心,假设没有阻止并发执行的锁定)。

答案 2 :(得分:1)

细节很简单就是你说“必须连续产生价值”,如果这是真的,那么CPU饱和度实际上是目标。

但是,如果你将“连续”定义为每秒X值,那么就有工作空间。

因为那时你可以在100%CPU上运行你的进程,测量一段时间内的值的数量,如果你发现它产生的值超过了必要的值(超过X / sec),那么你现在可以插入暂停适当的过程,直到价值率达到预期目标。

计划是持续监控和调整暂停以保持您的价值率。然后,您的过程将根据需要采用尽可能多的CPU来满足您的值/秒目标。

附录:

如果你有一个你满意的值/秒基准,那么插入睡眠将为其他应用程序提供“所有必要的优先级”,但仍然保持你的吞吐量。另一方面,如果您没有任何可靠的要求,那么要求是“在没有其他任何其他运行的情况下尽可能快地运行,如果某些其他进程在CPU中占主导地位,则不需要任何实际结果”,那么这确实是主机操作系统的内核问题,而不是JVM有任何直接,可移植的机制来解决。

在Unix系统上,你有nice(1)命令来调整进程(而不是线程)优先级,Windows有自己的机制。使用这些命令,您可以将Java进程的优先级置于“空闲”之上(默认的“进程”始终在没有其他任何运行时运行)。但它是特定于平台的,因为这是一个固有的平台特定问题。这可以通过启动Java程序的平台特定启动脚本(甚至是在执行实际代码之前检测平台并“做正确的事情”的Java启动程序)来管理。

大多数系统都允许您降低自己的流程优先级,但除非您是管理员/超级用户或拥有适合您的主机操作系统的任何角色,否则很少会让您提升。

答案 3 :(得分:0)

检查代码中是否有“紧密循环”。

while (true) {
  if (object.checkSomething()) {
    ...
  }
}

如果这样做,那么您将在数百万次可能不是时间关键的检查上烧掉CPU周期。 JVM将有义务(因为它不知道检查是否“重要”)并且您将获得100%的CPU。

如果你发现这样的循环,就像这样重写它们

while (true) {
  if (object.checkSomething()) {
    ...
  }
  try {
    Thread.sleep(100);
  } catch (InterruptedException e) {
    // purposefully do nothing
  }
}

并且睡眠将自动释放循环内的CPU,防止它运行得太快(并且检查条件太多次)。

答案 4 :(得分:-1)

非常有趣的帖子。我发现Java没有提供做我想做的事情的方法,唯一的方法是从外部 JVM。 我最终使用 nice 来改变我的测试(Linux)环境中的调度优先级,仍然需要为基于WIn的操作系统找到类似的东西。

非常感谢每个人的干预。