2017-12-15 20 views
2

私はSpringBootアプリケーションを持っています。 284 MBのメモリ。しかし、私は最大でアプリを始めることができます。 768 MBのメモリ。私が後でメモリを減らしても、私はいつも次のエラーを受け取ります:swisscom cloudfoundryのメモリが不足していますspringbootアプリケーション

[APP/PROC/WEB/0] ERR Cannot calculate JVM memory configuration: There is insufficient memory remaining for heap. Memory limit 384M is 
less than allocated memory 672509K (-XX:ReservedCodeCacheSize=240M, -XX:MaxDirectMemorySize=10M, -XX:MaxMetaspaceSize=109309K, -Xss1M * 300 threads) 

私はすでにこの問題なしでcfで同じアプリを使用しています。 CFで何が変わったのですか? 2〜3週間前はまだ働いていました。

ありがとうございました。

答えて

4

I am already using the same app in cf without this problem. What has changed in cf? Before 2 or 3 weeks it still worked.

あなたはパックV4をJavaビルドにアップグレードしている必要があります。 JBP v3を使用すると、メモリ量が少ないアプリケーションをプッシュすることができますが、そのバージョンのビルドパックでプッシュされたアプリケーションやメモリの制限が小さいため、クラッシュする可能性も非常に高くなりました。その理由は、JBP v3では、JBPが計算したときにJVMで使用されるすべてのメモリ領域を考慮していなかったため、アプリを起動させることができますが、あとでメモリ制限を超えてしまう可能性があります。 JBP v4でメモリを計算する方法がより正確になり、JVMのすべてのメモリ領域が考慮されます。

最終的な結果は、JBP v4のステージングで、次のエラーを見ることができるRAMの1G未満で動作するアプリ、および512M以下で動作するアプリで、ほぼ確実にステージングでこのエラーが表示されるということです。

ERR Cannot calculate JVM memory configuration: There is insufficient memory remaining for XXXX 

しかし、成功した段階を行うためにJavaアプリケーションをクラッシュさせる大幅ににくいです。

https://discuss.pivotal.io/hc/en-us/articles/115011717548-Insufficient-memory-when-using-Java-Buildpack-4-0-

だから、これはあなたがRAMの1G未満でJavaアプリケーションを実行することはできません意味ですか?いいえ、できますが、チューニングが必要になります。ここでは、いくつかのメモリを節約するためにチューニングできるもののリストを示します。

  • スレッド数。 JBPでは、アプリケーションが250スレッドで動作することを前提としています。これは、Tomcatの内部用のものが約50、要求処理用のものが約200あるWebアプリケーションにはよく使われます。この値を小さくすることはできますが、アプリが設定したスレッド数を超えないようにする必要があります。そうしないと、アプリがクラッシュする可能性があります。あなたにとって、これはSpring BootによるTomcatの設定を調整します。 JBPための下糸カウントの

    例:

    cf set-env my-application JBP_CONFIG_OPEN_JDK_JRE '{ memory_calculator: { stack_threads: 50 } }'

    春ブーツの下側のスレッド数のExapleがapplication.properties:

    server.tomcat.max-threads=25

    注:これはただのリクエストですスレッドを処理します。 Tomcat自体にスレッドがあり、アプリケーションがスレッドを作成する可能性があります。スレッドダンプまたはJVisualVMを実際に調べて、アプリケーションに必要なスレッドの数を確認してください(つまり、測定値、推測しないでください)。

  • スレッドスタックサイズ(-Xss)。これはJVMに渡される値で、スレッドごとに必要なメモリ量を制御します。デフォルトは1Mで、これは非常に高い値です。ほとんどの場合、Java 8で許容される最小値である160Kに安全に下げることができます.250のスレッドを持ち、この変更を行うと、(1M * 250) - (160K - 250)= 211MのRAM 。

    注:スレッドスタックのサイズを小さくすると、アプリにStackOverflow例外が表示されます。それが起こった場合は、落ち着いて、値が上がるまで上げてください。

  • Reserved Code Cacheを下げます。これは、JVMがJITコードをキャッシュする場所です。デフォルトは240Mです。この値を低くすることはできますが、これはパフォーマンスに絶対に影響する可能性があるので注意してください。 errors at runtime if this value is not high enoughもご覧ください。

    もう一度、アプリが推測するのではなく、必要なものを測定する方がよいでしょう。 JVM's NMTを使用して測定できるはずです。

  • JVMで使用されるメモリの他の領域をヒープ&メタスペースのように手動で調整することができます。 JBP v4では、JAVA_OPTS環境変数をcf set-envまたはmanifest.ymlファイルに設定するのと同じくらい簡単です。明らかに、これらの値を低くすると、あまりにも低くならないように注意する必要があります。その場合、OutOfMemoryErrorsになります。

    注:ヒープまたはメタスペースのように、リージョンを設定しない場合、JBPは手動カスタマイズ後に残っているものをスマートに計算します。

希望します。

+0

これは私がこれまで見てきた最良の説明です。ありがとう! – fischermatte

+0

あなたには非常に良い答えをありがとうございます。今それは動作します。 – surfspider

0

私は雲のファウンドリでのJavaアプリケーションのメモリ処理の専門家ではないですが、私は考え出したものから1には、次の知っている必要があります:

  • Javaアプリケーションが正常にJava Buildpack経由で展開されています。 manifest.ymlにバージョンを定義しない場合は、マスターの ブランチが使用されます。マスターブランチは常に変更されるため、 デプロイメントパラメータも変更される可能性があります。
  • Javaのビルドパックは-XmxのようなJVMのメモリパラメータを評価するためにJava Buildpack Memory Calculatorを使用しています。 manifest.ymlでこれらのパラメータを自分で設定することもできますが、クラウドファウンドリのスケーリング機能を使用する場合はお勧めしません。
  • そう - あなたは雲のファウンドリアプリは500MBのメモリを使用することを許可され、ビルドパックの計算はより多くのを評価し、それが動作し、いくつかのエラーにつながらない可能性があることを定義するとき。

マニフェストでできることは、メモリ計算機のドキュメントに記載されているすべてのパラメータを使って遊ぶことです。たとえば、計算機にヒントを少なくしたい場合は、帽子に必要なスレッド数を少なくすることができます(memory_calculator: { stack_threads: 100}

メモリパラメータがハードコーディングされていればいいです:ここでは、Spring Boot 2/Java 9 app私は400 MBの制限で使用しています。それは私のために働くが、おそらくすぐにコピーするものではない。それはあなたのアプリに依存します。

applications: 
- name: demo-app 
    path: target/demo-app-1.0.0.jar 
    instances: 1 
    buildpack: https://github.com/cloudfoundry/java-buildpack.git 
    memory: 400m 
    env: 
    JAVA_OPTS: '-XX:MaxMetaspaceSize=80780K -Xss512k -Xmx200M -XX:ReservedCodeCacheSize=16M -XX:MaxDirectMemorySize=16M' 
    JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 9.+ } }' 
関連する問題