Java 如何减少spring boot内存使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44491257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to reduce spring boot memory usage?
提问by Hailong Li
I'm using spring boot to develope client application. and when run spring boot application(using fully executable jar), the memory usage is about 190M in x64 server, and 110M in x86 server.
我正在使用 spring boot 来开发客户端应用程序。并且在运行spring boot应用程序(使用完全可执行的jar)时,x64服务器中的内存使用量约为190M,x86服务器中为110M。
my jvm option is (-Xmx64M -Xms64M -XX:MaxPermSize=64M -server), why in x64 server, memory usage is so big? how to reduce memory usage below 150M?
我的 jvm 选项是 (-Xmx64M -Xms64M -XX:MaxPermSize=64M -server),为什么在 x64 服务器中,内存使用量如此之大?如何将内存使用量减少到 150M 以下?
thanks.
谢谢。
采纳答案by CCob
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.
这里的游戏有点晚了,但我在 Docker 上使用容器化的 Spring Boot 应用程序遇到了同样的问题。在带有单个控制器和嵌入式 Tomcat 的最简单的 Spring Boot 应用程序上,您将获得的最少总内存约为 72M。加入 Spring Data REST、Spring Security 和一些 JPA 实体,您将看到最少 200M-300M。通过使用以下 JVM 选项,您可以将一个简单的 Spring Boot 应用程序减少到大约 7200 万。
With-XX:+UseSerialGC
This will perform garbage collection inline with the thread allocating the heap memory instead of a dedicated GC thread(s)
With-XX:+UseSerialGC
这将与分配堆内存的线程内联执行垃圾收集,而不是专用的 GC 线程
With-Xss512k
This will limit each threads stack memory to 512KB instead of the default 1MB
使用-Xss512k
这会将每个线程堆栈内存限制为 512KB 而不是默认的 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.
With-XX:MaxRAM=72m
This 将限制 JVM 对堆和非堆托管内存的计算在此值的限制范围内。
In addition to the above JVM options you can also use the following property inside your application.properties
file:
除了上述 JVM 选项之外,您还可以在application.properties
文件中使用以下属性:
server.tomcat.max-threads = 1
This will limit the number of HTTP request handler threads to 1 (default is 200)
server.tomcat.max-threads = 1
这会将 HTTP 请求处理程序线程的数量限制为 1(默认为 200)
Here is an example of docker stats
running a verysimple 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.
这是docker stats
运行具有上述限制和 docker参数的非常简单的 Spring Boot 应用程序的示例-m 72m
。如果我将值降低到低于此值,我将无法启动应用程序。
83ccc9b2156d: Mem Usage: 70.36MiB / 72MiB | Mem Percentage: 97.72%
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.
在这里您可以看到退出时所有本机和 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)
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
也不要期望从中获得任何不错的性能,因为我认为 GC 会在此设置下频繁运行,因为它没有很多空闲内存可供使用
回答by Hailong Li
After search, i found it's already have answer in stackoveflow. Spring Boot memory consumption increases beyond -Xmx option
搜索后,我发现它在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.
because spring boot starts around 50 threads per default for http service(Tomcat or Undertow, Jetty), and its use 1 MB per thread(64bit jvm default setting).
因为对于 http 服务(Tomcat 或 Undertow、Jetty),spring boot 每个默认启动大约 50 个线程,并且每个线程使用 1 MB(64 位 jvm 默认设置)。
SO the in 64bit jvm, the memory usage is heap(64M) + Permgen(max 64M) + thread stacks(1M x 50+) + native handles.
所以在 64 位 jvm 中,内存使用是堆(64M)+ Permgen(最大 64M)+ 线程堆栈(1M x 50+)+ 本机句柄。
references:
参考:
回答by Yassine Abainou
You can use -XX:+UseSerialGC as JVM Argument to specify Serial Garbage Collector which is best choice to reduce Memory Heap .
您可以使用 -XX:+UseSerialGC 作为 JVM 参数来指定串行垃圾收集器,这是减少内存堆的最佳选择。