The recommendation for picking the size of an application is to pick a large memory limit for the Java or JVM based applications. Then monitoring the application's usage and gradually lowering the limit until you reach a point where you are comfortable with the overhead and in being able to handle the peak usage. We recommend this approach because memory and monitoring are cheap. It's not a labor-intensive process and it should keep the applications up and be running.
Here are some things specific to the platform that you should consider when picking your memory limit.
To help with your calculations, here are some common memory limits and a break down of how the memory is allocated for the JVM. These are based on the default rules in the Java Build Pack at the time this article was written, which are listed below.
This article focuses on the aspects of sizing an application that is specific to PWS. Consider the best practices for sizing the Java and JVM-based applications.
While the Java buildpack does it's best to configure the JVM so that it does not exceed the memory limit, there is no way to completely prevent your app from exceeding its memory limit. The JVM does not allow you to cap the native or thread stack memory usage which means that given the right conditions, it could grow beyond the expected amounts causing to exceed the memory limit.
For more details on how the Java buildpack allocates memory for the application, see this article. If you want to make adjustments to the way the buildpack allocates the memory by default, do so by setting specific environment variables (`cf set-env
` or in your manifest.yml
file). More information on this can be found here.
Please also note that to change the JVM options, you must restage the application. This is either done by running cf push
or cf restage
. It is not sufficient to run cf scale
, cf restart
or any other command that does not completely restage the application.
-Xss
is per thread and not a total memory limit. It's generally going to be set at or very close to 1M/thread.For an application with a 512M memory limit, the JVM will get roughly 373M for the heap, 64M for the PermGen/Metaspace and a 1M thread stack size. This leaves roughly 75M for native memory and thread stacks. At 1M per thread, that would give you at most 75 threads.
For an application with a 1G memory limit, the JVM will get roughly 768M for the heap, 102M for the PermGen/Metaspace and a 1M thread stack size. This leaves roughly 154M for native memory and thread stacks. At 1M per thread, that would give you at most 154 threads.
For an application with a 2G memory limit, the JVM will get roughly 1536M for the heap, 204M for the PermGen/Metaspace and a 1M thread stack size. This leaves roughly 308M for native memory and thread stacks. At 1M per thread, that would give you at most 308 threads.
This article focuses on the aspects of sizing your application that are specific to PWS. You should also take into consideration any normal best practices for sizing your Java & JVM based applications.
While the Java buildpack does it's best to configure the JVM so that it does not exceed the memory limit you specify, there is no way to completely prevent your app from exceeding it's memory limit. The JVM does not allow you to cap the native or thread stack memory usage, which means that given the right conditions it could grow beyond the expected amounts causing you to exceed your memory limit.