how to reduce spring boot memory usage?

ghz 1years ago ⋅ 358 views

Question

I'm using spring boot to develop a client application. and when run the spring boot application(using a fully executable jar), the memory usage is about 190M in x64 server, and 110M in x86 server.

My JVM options are (-Xmx64M -Xms64M -XX:MaxPermSize=64M -server), why is it that in the x64 server, memory usage is so big? how to reduce memory usage below 150M?

thanks.


Answer

Little late to the game here, but I suffered the same issue with a containerised Spring Boot application on Docker. The bare minimum you'll get away with is around 72M total memory on the simplest of Spring Boot applications with a single controller and embedded Tomcat. Throw in Spring Data REST, Spring Security and a few JPA entities and you'll be looking at 200M-300M minimum. You can get a simple Spring Boot app down to around 72M total by using the following JVM options.

With -XX:+UseSerialGC This will perform garbage collection inline with the thread allocating the heap memory instead of a dedicated GC thread(s)

With -Xss512k This will limit each threads stack memory to 512KB instead of the default 1MB

With -XX:MaxRAM=72m This will restrict the JVM's calculations for the heap and non heap managed memory to be within the limits of this value.

In addition to the above JVM options you can also use the following property inside your application.properties file:

server.tomcat.max-threads = 1 This will limit the number of HTTP request handler threads to 1 (default is 200)


Here is an example of docker stats running a very simple Spring Boot application with the above limits and with the docker -m 72m argument. If I decrease the values any lower than this I cannot get the app to start.

83ccc9b2156d: Mem Usage: 70.36MiB / 72MiB | Mem Percentage: 97.72%

And here you can see a breakdown of all the native and java heap memory on exit.

Native Memory Tracking:

Total: reserved=1398681KB, committed=112996KB
-                 Java Heap (reserved=36864KB, committed=36260KB)
                            (mmap: reserved=36864KB, committed=36260KB) 

-                     Class (reserved=1086709KB, committed=43381KB)
                            (classes #7548)
                            (  instance classes #7049, array classes #499)
                            (malloc=1269KB #19354) 
                            (mmap: reserved=1085440KB, committed=42112KB) 
                            (  Metadata:   )
                            (    reserved=36864KB, committed=36864KB)
                            (    used=36161KB)
                            (    free=703KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=1048576KB, committed=5248KB)
                            (    used=4801KB)
                            (    free=447KB)
                            (    waste=0KB =0.00%)

-                    Thread (reserved=9319KB, committed=938KB)
                            (thread #14)
                            (stack: reserved=9253KB, committed=872KB)
                            (malloc=50KB #74) 
                            (arena=16KB #26)

-                      Code (reserved=248678KB, committed=15310KB)
                            (malloc=990KB #4592) 
                            (mmap: reserved=247688KB, committed=14320KB) 

-                        GC (reserved=400KB, committed=396KB)
                            (malloc=272KB #874) 
                            (mmap: reserved=128KB, committed=124KB) 

-                  Compiler (reserved=276KB, committed=276KB)
                            (malloc=17KB #409) 
                            (arena=260KB #6)

-                  Internal (reserved=660KB, committed=660KB)
                            (malloc=620KB #1880) 
                            (mmap: reserved=40KB, committed=40KB) 

-                    Symbol (reserved=11174KB, committed=11174KB)
                            (malloc=8417KB #88784) 
                            (arena=2757KB #1)

-    Native Memory Tracking (reserved=1858KB, committed=1858KB)
                            (malloc=6KB #80) 
                            (tracking overhead=1852KB)

-               Arena Chunk (reserved=2583KB, committed=2583KB)
                            (malloc=2583KB) 

-                   Logging (reserved=4KB, committed=4KB)
                            (malloc=4KB #179) 

-                 Arguments (reserved=17KB, committed=17KB)
                            (malloc=17KB #470) 

-                    Module (reserved=137KB, committed=137KB)
                            (malloc=137KB #1616)

Don't expect to get any decent performance out of this either, as I would imagine the GC would be running frequently with this setup as it doesn't have a lot of spare memory to play with