У меня есть Java-приложение, работающее на Java 8 внутри контейнера докеров. Процесс запускает сервер Jetty 9 и развертывается веб-приложение. Следующие опции JVM передаются: -Xms768m -Xmx768m
.Использование памяти процесса Java (jcmd vs pmap)
Недавно я заметил, что процесс потребляет много памяти:
$ ps aux 1
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
app 1 0.1 48.9 5268992 2989492 ? Ssl Sep23 4:47 java -server ...
$ pmap -x 1
Address Kbytes RSS Dirty Mode Mapping
...
total kB 5280504 2994384 2980776
$ jcmd 1 VM.native_memory summary
1:
Native Memory Tracking:
Total: reserved=1378791KB, committed=1049931KB
- Java Heap (reserved=786432KB, committed=786432KB)
(mmap: reserved=786432KB, committed=786432KB)
- Class (reserved=220113KB, committed=101073KB)
(classes #17246)
(malloc=7121KB #25927)
(mmap: reserved=212992KB, committed=93952KB)
- Thread (reserved=47684KB, committed=47684KB)
(thread #47)
(stack: reserved=47288KB, committed=47288KB)
(malloc=150KB #236)
(arena=246KB #92)
- Code (reserved=257980KB, committed=48160KB)
(malloc=8380KB #11150)
(mmap: reserved=249600KB, committed=39780KB)
- GC (reserved=34513KB, committed=34513KB)
(malloc=5777KB #280)
(mmap: reserved=28736KB, committed=28736KB)
- Compiler (reserved=276KB, committed=276KB)
(malloc=146KB #398)
(arena=131KB #3)
- Internal (reserved=8247KB, committed=8247KB)
(malloc=8215KB #20172)
(mmap: reserved=32KB, committed=32KB)
- Symbol (reserved=19338KB, committed=19338KB)
(malloc=16805KB #184025)
(arena=2533KB #1)
- Native Memory Tracking (reserved=4019KB, committed=4019KB)
(malloc=186KB #2933)
(tracking overhead=3833KB)
- Arena Chunk (reserved=187KB, committed=187KB)
(malloc=187KB)
Как вы можете видеть, что есть огромная разница между RSS (2,8GB) и то, что на самом деле показывается носителем памяти В.М. статистика (1,0 ГБ, 1,3 ГБ).
Почему существует такая огромная разница? Я понимаю, что RSS также показывает распределение памяти для разделяемых библиотек, но после анализа подробного вывода pmap
я понял, что это не проблема разделяемых библиотек, а память потребляется кем-то, что называется структурой [anon]. Почему JVM выделяет столько анонимных блоков памяти?
Я искал и нашел следующую тему: Why does a JVM report more committed memory than the linux process resident set size? Однако случай, описанный здесь отличается, потому что меньше использование памяти показывается RSS, чем статистика виртуальной машины Java. Я имею противоположную ситуацию и не могу понять причину.
У меня такая же проблема, у меня есть java-процесс с Xmx 1.5g (Oracle Jvm), который потребляет около 3,1 г, когда я вижу в команде TOP, однако такое же приложение, когда я запускаю openjdk, он потребляет около 2,3 ГБ выше выделенного xmx), я до сих пор не нашел ответа на это. Дайте мне знать, если вы найдете решение. Спасибо –