Java 如何减少spring启动内存的使用?

Java 如何减少spring启动内存的使用?,java,memory,spring-boot,Java,Memory,Spring Boot,我正在使用SpringBoot开发一个客户端应用程序。 当运行spring引导应用程序(使用完全可执行的jar)时,x64服务器的内存使用量约为190M,x86服务器的内存使用量约为110M 我的JVM选项是(-Xmx64M-Xms64M-XX:MaxPermSize=64M-server), 为什么在x64服务器中,内存使用量如此之大? 如何将内存使用减少到150M以下 谢谢。在搜索之后,我发现它已经在stackoveflow中找到了答案。 因为spring引导对于http服务(Tomcat

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

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


谢谢。

在搜索之后,我发现它已经在stackoveflow中找到了答案。

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

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

参考资料:


游戏在这里进行得有点晚,但我在Docker上的容器化Spring Boot应用程序中遇到了同样的问题。在最简单的Spring引导应用程序上,您可以使用的最小内存约为72M,该应用程序只有一个控制器和嵌入式Tomcat。再加上SpringDataREST、SpringSecurity和一些JPA实体,您将看到最小值为200-300米。通过使用以下JVM选项,您可以将一个简单的Spring Boot应用程序的总数减少到72M左右

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

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

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

除了上面的JVM选项之外,您还可以在
应用程序中使用以下属性。属性
文件:

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


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

83ccc9b2156d:Mem使用量:70.36MiB/72MiB | Mem百分比: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将在这个设置中频繁运行,因为它没有很多空闲内存可供使用。

您可以使用-XX:+UseSerialGC作为JVM参数来指定串行垃圾收集器,这是减少内存堆的最佳选择。

x64(64位)指针的大小是x86(32位)指针的两倍,因此64位模式下的内存使用量必然会更大。是的,但除了heap+Perm之外,我不知道使用了什么内存。我设置了最大堆大小64M,最大perm大小64M,但是为什么使用了大约60M(190M-64Mx2),我不能减少它。@海龙里你提到了导致内存增加的原因。但是如何减少它呢?稍晚一点,但这篇文章可能有助于减少内存大小?是不是因为嵌入了jar文件的tomcat服务器?如果我们以war文件内存减少的方式运行它?这个公认的答案并不能回答这个问题。问题是如何减少内存消耗,而不是解释它为什么会占用大量内存。为什么这会有5次投票?它只是部分地回答了这个问题,理解为什么会发生某些事情有助于解决问题。这两个答案都很好,一个是细节,另一个是概述。他们互相赞美。2020年的救生员,我的heroku dyno不断抛出R14故障72MB的
-XX:MaxRAM
设置?!哈是的,我的应用程序启动速度为950MB。SpringBoot2.3.0,只不过是一些REST控制器。启动只需不到10秒,但即使没有收到任何请求,也没有对其施加任何负载,它会达到1GB并保持在那里。@JeneralJames这正是我在生产中遇到的情况。我越来越觉得这不是集装箱世界的技术。这确实适用于单片应用服务器和100个端点(控制器)。这就是为什么Java空间中的新技术,如quarkus,正是为了解决这个问题而出现的。甚至更好的平台,如Node/Go/.netcore,都是云/容器原生ARCH的基础。
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)