cloudfoundry / java-buildpack-memory-calculator

Cloud Foundry JVM Memory Calculator
Apache License 2.0
642 stars 70 forks source link

Stack memory calculation #13

Closed pborbas closed 6 years ago

pborbas commented 6 years ago

We run our app on pivotal's CF which runs memory calculator 3.9.0_RELEASE. Our JVM memory was 300MB less than our container limit, so I ran the memory calculator manually and realised that the -stackThreads argument affects the -Xmx value. Based on the docs it should decrease the heap with the calculated stack and increase stack size BUT the stack value remains -Xss1M no matter what the stackThread param is:

$ ./java-buildpack-memory-calculator-3.9.0_RELEASE -totMemory=1280M -loadedClasses=27000 -stackThreads=1 -poolType=metaspace -vmOptions=""
-XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=26269K -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=166601K -Xss1M -Xmx860824K
$ ./java-buildpack-memory-calculator-3.9.0_RELEASE -totMemory=1280M -loadedClasses=27000 -stackThreads=300 -poolType=metaspace -vmOptions=""
-XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=26269K -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=166601K -Xss1M -Xmx554648K

I see two problems:

  1. In memory/allocator.go, the calculateMaxHeapSize method never sets the stack size just decreases the heap = we lose memory.
  2. 1Mb/thread stack feels way too much for stack size compared to the JVM default 1MB which isn't tuned for a single threaded application.
nebhale commented 6 years ago

This is behaving as designed. The JVM's default is 1M/thread and we do not adjust defaults unless the default is unbounded (e.g. MaxDirectMemory, MaxMetaspaceSize). Changing the number of threads shouldn't and doesn't affect the size of each of those thread stacks. Instead, you should tune your thread stack size directly with cf set-env <APP> JAVA_OPTS '-Xss=<VALUE>'

pborbas commented 6 years ago

Thanks for the clarification. I read about the subject and what I didn't know that JVM reserves the Xss for each thread and this memory is outside of the configured memory values, so you must keep that memory unreserved.

nebhale commented 6 years ago

Yep, -Xss is a per-thread stack size. Glad this helped.