Ich verwende Spring Boot, um eine Client-Anwendung zu entwickeln. und wenn Sie die Spring Boot-Anwendung ausführen (mit einem vollständig ausführbaren JAR), beträgt die Speichernutzung etwa 190 MB auf einem x64-Server und 110 MB auf einem x86-Server.
Meine JVM-Optionen sind (-Xmx64M -Xms64M -XX:MaxPermSize=64M -server), warum ist die Speichernutzung auf dem x64-Server so groß? Wie kann die Speichernutzung auf unter 150 MB reduziert werden?
Danke.
Etwas spät zum Spiel hier, aber ich hatte das gleiche Problem mit einer containerisierten Spring Boot-Anwendung auf Docker. Das absolute Minimum, mit dem Sie davonkommen, ist etwa 72 MB Gesamtspeicher bei den einfachsten Spring Boot-Anwendungen mit einem einzigen Controller und eingebettetem Tomcat. Fügen Sie Spring Data REST, Spring Security und ein paar JPA-Einheiten hinzu, und Sie werden mindestens 200 Mio. bis 300 Mio. sehen. Mit den folgenden JVM-Optionen können Sie eine einfache Spring Boot-App auf insgesamt etwa 72 MB reduzieren.
Mit -XX:+UseSerialGC
Dadurch wird die Garbage Collection inline mit dem Thread durchgeführt, der den Heap-Speicher anstelle eines dedizierten GC-Threads zuweist.
Mit -Xss512k
Dadurch wird der Stack-Speicher jedes Threads auf 512 KB anstelle der Standardeinstellung von 1 MB begrenzt
Mit -XX:MaxRAM=72m
Dadurch werden die Berechnungen der JVM für den Heap- und Nicht-Heap-verwalteten Speicher so eingeschränkt, dass sie innerhalb der Grenzen dieses Werts liegen.
Zusätzlich zu den oben genannten JVM-Optionen können Sie auch die folgende Eigenschaft in Ihrer verwenden application.properties
Datei:
server.tomcat.max-threads = 1
Dadurch wird die Anzahl der HTTP-Request-Handler-Threads auf 1 begrenzt (Standard ist 200).
Hier ist ein Beispiel für docker stats
laufen a sehr einfache Spring Boot-Anwendung mit den oben genannten Grenzen und mit dem Docker -m 72m
Streit. Wenn ich die Werte weiter verringere, kann die App nicht gestartet werden.
83ccc9b2156d: Mem Usage: 70.36MiB / 72MiB | Mem Percentage: 97.72%
Und hier sehen Sie eine Aufschlüsselung des gesamten nativen und Java-Heap-Speichers beim Beenden.
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)
Erwarten Sie auch keine anständige Leistung, da ich mir vorstellen kann, dass der GC mit diesem Setup häufig ausgeführt wird, da er nicht viel freien Speicher zum Spielen hat
Nach der Suche habe ich festgestellt, dass es bereits eine Antwort in Stackoveflow gibt. Der Spring Boot-Speicherverbrauch steigt über die Option -Xmx hinaus
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.
weil Spring Boot standardmäßig etwa 50 Threads für den HTTP-Dienst (Tomcat oder Undertow, Jetty) startet und 1 MB pro Thread verwendet (64-Bit-JVM-Standardeinstellung).
SO beträgt die Speichernutzung in 64-Bit-JVM Heap (64 MB) + Permgen (max. 64 MB) + Thread-Stacks (1 MB x 50+) + native Handles.
Verweise:
Sie können -XX:+UseSerialGC als JVM-Argument verwenden, um den Serial Garbage Collector anzugeben, der die beste Wahl zum Reduzieren von Memory Heap ist.
x64-Zeiger (64-Bit) sind doppelt so groß wie x86-Zeiger (32-Bit), sodass die Speichernutzung im 64-Bit-Modus zwangsläufig größer ist.
–Andreas
12. Juni 2017 um 4:27 Uhr
ja, aber ich weiß nicht, welcher Speicher außer Heap + Perm verwendet wird. Ich habe die maximale Heap-Größe auf 64 MB und die maximale Perm-Größe auf 64 MB eingestellt, aber warum werden ungefähr 60 MB (190 MB – 64 MB x 2) verwendet, und ich kann sie nicht reduzieren.
– Hailong Li
12. Juni 2017 um 5:26 Uhr
@ HailongLi Sie haben erwähnt, was zu einer Erhöhung des Speichers führt. Aber wie kann man es reduzieren?
– Krisch
12. Mai 2018 um 9:33 Uhr
Etwas später, aber dieser Beitrag kann helfen dzone.com/articles/…
– Sigrist
21. September 2018 um 14:35 Uhr