私は4ギガバイトのハードメモリ制限がありドッカー容器内のJavaプログラムを実行していますよ。私は3ギガバイトに最大ヒープを設定しましたが、まだJavaプログラムが限界を超え、殺され(OOMKilled)。
私の質問は:セットのコンテナ限度を尊重し、代わりに、限界を超え割り当て、そのお尻がホストカーネルによって蹴ら取得しようとしているのでOutOfMemoryExceptionをスローするためにどうすればよいのconfigureのJava?
アップデート:私は経験豊富なJava開発者だし、JVMの公正な理解を持っています。私は、最大ヒープを設定する方法を知っているが、誰もがに制限を設定する方法を知っているのだろうか、総メモリそのOSからのJVMプロセスクレーム。
Javaアプリケーションがコンテナ内で実行された場合、JVMエルゴノミクス(ホストの能力に基づいて動的にリソースの割り当てを担当している)、それはコンテナ内で実行されている知っていないと、それは、Javaアプリケーションが使用するリソースの数を算出し、あなたのコンテナを実行しているホストに基づきます。あなたはコンテナに制限を設定した場合、それは問題ではない、ということを考えると、JVMは、その計算を行うための拠点として、ホストのリソースがかかります。
JDK 8u131 +およびJDK 9からは、JVMの人間工学がCGgroupsからメモリ値を読み取ることができます実験的なVMのオプションがあります。それを有効にするには、JVMに次のフラグを渡す必要があります。
-XX:+ UnlockExperimentalVMOptionsと-XX:+ UseCGroupMemoryLimitForHeap
あなたはこれらのフラグを有効にした場合、JVMは、コンテナ内で実行されていることに気づくであろうと、JVMの人間工学は、コンテナ限度ではなく、ホストの能力に基づいてアプリのリソースを計算するようになります。
フラグを有効にします:
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar app.jar
あなたは、動的にENV変数を使用してコンテナにJVMオプションを渡すことができます。
例:
あなたのアプリを実行するためのコマンドのような何かをしたいと思います。
$ java ${JAVA_OPTIONS} -jar app.jar
そして、ドッキングウィンドウの実行コマンドは次のようにENV変数を渡す必要があります。
$ docker run -e JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" myJavaImage
お役に立てれば!