java - Docker 容器 - JVM 内存峰值 - Arena block 内存空间

标签 java docker memory jvm

在针对在 ECS/EC2/Docker/Centos7/Tomcat/OpenJDK8 环境中运行的 Java Web 应用程序进行性能测试时,我观察到 JVM 内存中有一个大的离散峰值。

性能测试非常简单,它包括对位于 Elastic Container Service 管理的 EC2 主机上运行的一对 Docker 容器前面的 AWS Application Load Balancer 的连续并发请求。通常,并发级别是 30 个并发负载测试客户端连接/线程。几分钟之内,其中一个 Docker 容器通常会受到影响。

内存峰值似乎出现在非堆内存中。具体来说,内存峰值似乎与 Arena Chunk 内存空间有关。比较未经历峰值的 JVM 和已经历峰值的 JVM 的内存占用时,ThreadArena Chunk 内存空间脱颖而出。

下面是 VM internal memory 的比较使用 jcmd 实用程序。

请注意 Arena Chunk 内存和相对较高的 Thread 内存数量。

测试的并发级别可以对Tomcat请求线程池中的线程产生即时需求。但是,峰值并不总是出现在第一波请求中。

你见过类似的东西吗?您知道是什么导致了峰值吗?


Docker 统计

内存峰值容器:

Mon Oct  9 00:31:45 UTC 2017
89440337e936        27.36%              530 MiB / 2.93 GiB      17.67%              15.6 MB / 24.1 MB   122 MB / 2.13 MB    0
Mon Oct  9 00:31:48 UTC 2017
89440337e936        114.13%             2.059 GiB / 2.93 GiB    70.29%              16.3 MB / 25.1 MB   122 MB / 2.13 MB    0

普通容器:

Mon Oct  9 00:53:41 UTC 2017
725c23df2562        0.08%               533.4 MiB / 2.93 GiB   17.78%              5 MB / 8.15 MB      122 MB / 29.3 MB    0
Mon Oct  9 00:53:44 UTC 2017
725c23df2562        0.07%               533.4 MiB / 2.93 GiB   17.78%              5 MB / 8.15 MB      122 MB / 29.3 MB    0

虚拟机内存

内存峰值 JVM:

# jcmd 393 VM.native_memory summary
393:

Native Memory Tracking:

Total: reserved=1974870KB, committed=713022KB
-                 Java Heap (reserved=524288KB, committed=524288KB)
                            (mmap: reserved=524288KB, committed=524288KB) 

-                     Class (reserved=1096982KB, committed=53466KB)
                            (classes #8938)
                            (malloc=1302KB #14768) 
                            (mmap: reserved=1095680KB, committed=52164KB) 

-                    Thread (reserved=8423906KB, committed=8423906KB)
                            (thread #35)
                            (stack: reserved=34952KB, committed=34952KB)
                            (malloc=114KB #175) 
                            (arena=8388840KB #68)

-                      Code (reserved=255923KB, committed=37591KB)
                            (malloc=6323KB #8486) 
                            (mmap: reserved=249600KB, committed=31268KB) 

-                        GC (reserved=6321KB, committed=6321KB)
                            (malloc=4601KB #311) 
                            (mmap: reserved=1720KB, committed=1720KB) 

-                  Compiler (reserved=223KB, committed=223KB)
                            (malloc=93KB #276) 
                            (arena=131KB #3)

-                  Internal (reserved=2178KB, committed=2178KB)
                            (malloc=2146KB #11517) 
                            (mmap: reserved=32KB, committed=32KB) 

-                    Symbol (reserved=13183KB, committed=13183KB)
                            (malloc=9244KB #85774) 
                            (arena=3940KB #1)

-    Native Memory Tracking (reserved=1908KB, committed=1908KB)
                            (malloc=8KB #95) 
                            (tracking overhead=1900KB)

-               Arena Chunk (reserved=18014398501093554KB, committed=18014398501093554KB)
                            (malloc=18014398501093554KB) 

-                   Unknown (reserved=38388KB, committed=38388KB)
                            (mmap: reserved=38388KB, committed=38388KB) 

普通 JVM:

# jcmd 391 VM.native_memory summary
391:

Native Memory Tracking:

Total: reserved=1974001KB, committed=710797KB
-                 Java Heap (reserved=524288KB, committed=524288KB)
                            (mmap: reserved=524288KB, committed=524288KB) 

-                     Class (reserved=1096918KB, committed=53738KB)
                            (classes #9005)
                            (malloc=1238KB #13654) 
                            (mmap: reserved=1095680KB, committed=52500KB) 

-                    Thread (reserved=35234KB, committed=35234KB)
                            (thread #35)
                            (stack: reserved=34952KB, committed=34952KB)
                            (malloc=114KB #175) 
                            (arena=168KB #68)

-                      Code (reserved=255261KB, committed=35237KB)
                            (malloc=5661KB #8190) 
                            (mmap: reserved=249600KB, committed=29576KB) 

-                        GC (reserved=6321KB, committed=6321KB)
                            (malloc=4601KB #319) 
                            (mmap: reserved=1720KB, committed=1720KB) 

-                  Compiler (reserved=226KB, committed=226KB)
                            (malloc=96KB #317) 
                            (arena=131KB #3)

-                  Internal (reserved=2136KB, committed=2136KB)
                            (malloc=2104KB #11715) 
                            (mmap: reserved=32KB, committed=32KB) 

-                    Symbol (reserved=13160KB, committed=13160KB)
                            (malloc=9221KB #85798) 
                            (arena=3940KB #1)

-    Native Memory Tracking (reserved=1890KB, committed=1890KB)
                            (malloc=8KB #95) 
                            (tracking overhead=1882KB)

-               Arena Chunk (reserved=178KB, committed=178KB)
                            (malloc=178KB) 

-                   Unknown (reserved=38388KB, committed=38388KB)
                            (mmap: reserved=38388KB, committed=38388KB) 

最佳答案

A glibc/malloc option似乎修复了这个 MALLOC_PER_THREAD=0。但是,我决定使用 debian/openjdk docker base image而不是 centos,这也解决了这个问题。

关于java - Docker 容器 - JVM 内存峰值 - Arena block 内存空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46638821/

相关文章:

用户未选择文件时 JAVA 禁用按钮

java - Spring Data Rest - 具有默认值的参数

Docker 用户进出容器 : what is the correspondence (UID/GID), 看到我不明白的效果

postgresql - 未绑定(bind)的 docker 容器卷中的数据是否提交给图像?

Python 2.6 GC出现清理对象,但内存并未释放

java - 如何使用 mockito/powermock 模拟 Google 的地理编码 API 请求?

java - 如何设置 JAAS(在 jaas.conf 中)以使用 NTLoginModule?

amazon-web-services - Docker 上下文不变(使用 Docker 上下文)

c - 任何查询分配 block 大小的函数?

c - gsoap 为结构的动态数组分配内存。