8

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

我需要的是说明 Java 中是否存在确保线程不占用全部 CPU 的方法。

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

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

任何帮助将非常感激。

4

5 回答 5

6

我需要的是说明 Java 中是否存在确保线程不占用全部 CPU 的方法。

除了调整您的应用程序以使用更少的 CPU 之外,我不知道在 Java 中执行此操作。

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

在 JVM 之外,您可以使用 ~unixnice命令来影响正在运行的 JVM 的优先级以不控制系统。如果可用,这将为其提供 CPU,但会让其他应用程序获得更多 CPU。

于 2012-09-06T14:26:23.650 回答
2

我认为您想要比设置线程优先级更可靠的东西吗?

如果您想要限制某些不断生成值的代码的执行,您需要考虑将线程所做的工作分块,并在您自己的计时器中进行编码。例如,java.util.Timer允许以固定速率调度执行

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

于 2012-09-06T14:28:03.573 回答
1

细节很简单,您说“必须不断生成值”,如果这是极端的话,那么CPU饱和实际上就是目标。

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

因为那时您可以在 100% CPU 上运行您的进程,随时间测量值的数量,如果您发现它生成的值比必要的多(超过 X/秒),那么您现在可以将暂停插入到进程中直到价值率达到您想要的目标为止。

该计划是持续监控和调整暂停,以随着时间的推移保持您的价值率。然后,您的进程将占用尽可能多的 CPU 来满足您的 values/sec 目标。

附加物:

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

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

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

于 2012-09-06T14:37:01.010 回答
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
  }
}

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

于 2012-09-06T14:37:39.157 回答
-1

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

Everyone's intervention has been much appreciated.

于 2012-09-07T20:10:52.900 回答