Java: JVM が使用できるコアの数を制限する

Java: JVM が使用できるコアの数を制限する

複数のユーザーが 60 コアのコンピューティング サーバー (Linux/Ubuntu ベース) で Java アプリケーションを実行しています。さまざまなアプリケーションがあり、そのほとんどは社内で開発されたものではありません。

システム管理者は、特定のユーザーの Java プロセスが特定の瞬間に 10 個のコアを使用することは問題ないと考えていますが、10 個を超えるコアは使用しないようにしたいと考えています。

プロセスがコンピューティング リソースを無制限に取得するのを防ぐために使用できる Java または OS 構成はありますか?

答え1

OS 面では:

  • 古典的な方法は、 で CPU アフィニティを設定することだと思いますtaskset

  • より良い代替案はcgroups

  • そして流行語となった解決策は、アプリケーションをドッカーコンテナ。ただし、Java 8 より前のバージョンでは、JVM は Docker によって課せられた制限を理解できません (8u131+ のバックポート後にのみ使用可能。CPU 部分については Java9 で実験的に使用可能かどうかは不明ですが、メモリについては使用可能で、Java10 では完全に使用可能)。

答え2

このビデオを見る価値はあると思います。https://vimeo.com/181900266

これは、Java と cgroup とコンテナの比較、および JVM が CPU の数などをどのように検出するかについて、非常に優れた概要を示しています。

これに基づいて、Java 8 までは、JVM は利用可能な CPU の数を決定する際に、常にすべての「オンライン」 CPU が利用可能であると見なします。これは、この目的で sysconf(_SC_NPROCESSORS_ONLN) が使用されるためです。cgroup 化されている場合やコンテナーに配置されている場合でも同様です。

Java 9 以降、JVM は sched_getaffinity() を使用するため、cpuset を使用して JVM の CPU の数を制御すると便利です。つまり、JVM は構成された CPU のみを認識します。たとえば、Docker の cpuset-cpus オプションを使用すると、JVM に制限が設定されます。注意! JVM に cpushare が構成されている場合、それでも問題は解決されません。cpushare のみが構成されている場合、JVM はシステム内のすべての CPU を認識します (コンテナー内にあるかどうかは関係ありません)。

答え3

他の人が言及しているもの (cgroup quota、cgroup cpuset) に加えて、オプションの値を指定することにより、ライブラリが要求したときに Java が報告する CPU の数を明示的に指示することもできます-XX:ActiveProcessorCount。 の値に基づいてスレッド数を自動的に選択するライブラリRuntime.getRuntime().availableProcessors()(Reactor の などSchedulers.parallel()) は、それに応じて自動的に構成されます。また、ガベージ コレクターの自動構成を通知する場合もあります。

関連情報