Docker容器 – JVM内存尖峰 – 竞技场块内存空间

在对ECS / EC2 / Docker / Centos7 / Tomcat / OpenJDK8环境中运行的Java Web应用程序进行性能testing期间,我正在观察JVM内存中的大量离散峰值。

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

内存峰值似乎在非堆内存中。 具体而言,内存峰值似乎与Arena Chunk内存空间有关。 比较没有经历过尖峰的JVM的内存占用量与ThreadArena Chunk内存空间的突出performance。

以下是使用jcmd实用程序的VM内部内存比较。

注意Arena Chunk内存的荒谬数字和Thread内存的相对较高的数字。

testing的并发级别可以为Tomcat请求线程池中的线程立即创build需求。 但是,在第一波请求中并不总是出现高峰。

你见过类似的东西吗? 你知道什么是造成穗?


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 

VM内部内存

内存尖刺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) 

glibc / malloc选项似乎解决了这个MALLOC_PER_THREAD=0 。 但是,我决定使用debian / openjdk docker基本映像而不是centos,这也解决了这个问题。