如何减少 spring boot 内存使用?

新手上路,请多包涵

我正在使用 spring boot 开发客户端应用程序。当运行 spring boot 应用程序(使用完全可执行的 jar)时,内存使用量在 x64 服务器中约为 190M,在 x86 服务器中约为 110M。

我的JVM选项是(-Xmx64M -Xms64M -XX:MaxPermSize=64M -server),为什么在x64服务器上,内存占用这么大?如何将内存使用量减少到 150M 以下?

谢谢。

原文由 Hailong Li 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

这里的游戏有点晚,但我在 Docker 上的容器化 Spring Boot 应用程序遇到了同样的问题。在具有单个控制器和嵌入式 Tomcat 的最简单的 Spring Boot 应用程序上,您将获得的最低限度是大约 72M 的总内存。加上 Spring Data REST、Spring Security 和一些 JPA 实体,您将看到最少 200M-300M。通过使用以下 JVM 选项,您可以将一个简单的 Spring Boot 应用程序的总大小降低到 72M 左右。

With -XX:+UseSerialGC 这将与分配堆内存的线程而不是专用的 GC 线程一起执行垃圾收集

使用 -Xss512k 这会将每个线程堆栈内存限制为 512KB 而不是默认的 1MB

With -XX:MaxRAM=72m 这会将 JVM 对堆和非堆管理内存的计算限制在该值的范围内。

除了上述 JVM 选项之外,您还可以在 application.properties 文件中使用以下属性:

server.tomcat.max-threads = 1 这会将 HTTP 请求处理程序线程数限制为 1(默认为 200)


这是 docker stats 运行一个 非常 简单的 Spring Boot 应用程序的示例,具有上述限制和 -m 72m 参数。如果我将值降低到低于此值,我将无法启动该应用程序。

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

在这里您可以看到退出时所有本机和 Java 堆内存的细分。

 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)

也不要期望从中获得任何不错的性能,因为我认为 GC 会使用此设置频繁运行,因为它没有很多备用内存可以使用

原文由 CCob 发布,翻译遵循 CC BY-SA 4.0 许可协议

经过搜索,我发现它已经在stackoveflow中找到了答案。 Spring Boot 内存消耗增加超过 -Xmx 选项

1. Number of http threads (Undertow starts around 50 threads per default, but you can increase / decrease via property the amount of threads needed)
2. Access to native routines (.dll, .so) via JNI
3. Static variables
4. Use of cache (memcache, ehcache, etc)
If a VM is 32 bit or 64 bit, 64 bit uses more memory to run the same application, so if you don't need a heap bigger than 1.5GB, so keep your application runnnig over 32 bit to save memory.

因为 spring boot 为 http 服务(Tomcat 或 Undertow,Jetty)默认启动大约 50 个线程,并且每个线程使用 1 MB(64 位 jvm 默认设置)。

所以在 64 位 jvm 中,内存使用量是堆(64M)+ Permgen(最大 64M)+ 线程堆栈(1M x 50+)+ 本机句柄。

参考:

原文由 Hailong Li 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题