Java:限制 JVM 可以使用的核心數量

Java:限制 JVM 可以使用的核心數量

多個使用者在 60 核心計算伺服器(基於 Linux/Ubuntu)上執行 java 應用程式。有不同的應用程序,其中大多數不是內部開發的。

雖然系統管理員認為給定使用者的 Java 進程在任何給定時刻使用 10 個核心是可以的,但她希望他們不要使用超過 10 個核心。

是否有任何 Java 或作業系統配置可用於防止進程無限制地取得運算資源?

答案1

在作業系統方面:

  • 我想說經典的方法是設定CPU親和力taskset

  • 更好的選擇是使用cgroups

  • 流行的解決方案是在以下位置運行您的應用程式碼頭工人容器。然而,在 Java 8 之前,JVM 無法理解 Docker 施加的限制(僅在 8u131+ 向後移植後可用,不確定它是否在 Java9 中作為實驗性用於 CPU 部分,但它用於內存,並且在Java10)

答案2

我想說,這個影片值得一看。https://vimeo.com/181900266

它很好地概述了 Java、cgroup、容器,以及 JVM 如何找出 CPU 的數量等。

基於此,我想說,直到 Java 8,JVM 都會以某種方式確定可用 CPU 的數量,它始終認為所有「線上」CPU 都可供它使用,因為它使用 sysconf(_SC_NPROCESSORS_ONLN) 來實現此目的。即使它被 cgroup'd 或放入容器中。

從 Java 9 開始,JVM 將使用 sched_getaffinity(),如果使用 cpuset 來控制 JVM 的 CPU 數量,將會有所幫助。即 JVM 將只看到配置的 CPU。例如,如果使用 Docker 的 cpuset-cpus 選項,那麼它實際上會對 JVM 造成限制。筆記!如果為 JVM 配置了 cpushare,則仍然無法解決問題。如果只配置了 cpushare,JVM 仍然會看到系統中的所有 CPU(無論它是否在容器中)。

答案3

除了其他人提到的(cgroup配額、cgroup cpuset)之外的另一種選擇是,您可以透過提供選項值來明確告訴Java在庫詢問時應該報告多少個CPU -XX:ActiveProcessorCount。任何根據 的值自動選擇線程數的庫Runtime.getRuntime().availableProcessors()(例如 Reactor 的Schedulers.parallel())都會相應地進行自身配置。它還可能通知垃圾收集器的自動配置。

相關內容