Java Arena Area 内存占用过高问题

Java JVM About 5,057 words

现象

使用top命令查看到Java内存RSS占用过高,堆内存并没有很大。

排查

使用pmap -x pid查看有很多anon,内存占用。

[root@local /]# pmap -x 1
3879282:   java -jar test.jar
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000732800000   70400   70400   70400 rw---   [ anon ]
0000000736cc0000 1051904       0       0 -----   [ anon ]
0000000777000000  140672  140672  140672 rw---   [ anon ]
000000077f960000 2103936       0       0 -----   [ anon ]
0000000800000000       8       8       8 rwx-- classes.jsa
0000000800002000    3900    3852    3836 rw--- classes.jsa
00000008003d1000    7004    6696       0 rw--- classes.jsa
0000000800aa8000       4       4       4 rw--- classes.jsa
0000000840000000    8832    8772    8772 rw---   [ anon ]
00000008408a0000 1039744       0       0 -----   [ anon ]
0000559cd6dd1000       4       4       0 r-x-- java
0000559cd6fd2000       4       4       4 r---- java
0000559cd6fd3000       4       4       4 rw--- java
0000559cd8675000     132      48      48 rw---   [ anon ]
00007f73e4000000     452     416     416 rw---   [ anon ]
00007f73e4071000   65084       0       0 -----   [ anon ]
00007f73ec000000     248     224     224 rw---   [ anon ]
00007f73ec03e000   65288       0       0 -----   [ anon ]
00007f73f0000000     132      72      72 rw---   [ anon ]
00007f73f0021000   65404       0       0 -----   [ anon ]
00007f73f4000000     244     224     224 rw---   [ anon ]
00007f73f403d000   65292       0       0 -----   [ anon ]
00007f73f8000000     396     392     392 rw---   [ anon ]
00007f73f8063000   65140       0       0 -----   [ anon ]
00007f73fc000000    3464    3452    3452 rw---   [ anon ]
00007f73fc362000   62072       0       0 -----   [ anon ]
00007f7400000000     216     192     192 rw---   [ anon ]
00007f7400036000   65320       0       0 -----   [ anon ]
00007f7404000000     216     188     188 rw---   [ anon ]
00007f7404036000   65320       0       0 -----   [ anon ]
00007f7408000000     208     180     180 rw---   [ anon ]
00007f7408034000   65328       0       0 -----   [ anon ]
00007f740c000000    1656    1632    1632 rw---   [ anon ]
00007f740c19e000   63880       0       0 -----   [ anon ]
00007f7410000000     272     244     244 rw---   [ anon ]
00007f7410044000   65264       0       0 -----   [ anon ]
00007f7414000000    2664    2656    2656 rw---   [ anon ]
00007f741429a000   62872       0       0 -----   [ anon ]
00007f7418000000     296     284     284 rw---   [ anon ]
00007f741804a000   65240       0       0 -----   [ anon ]

开启NMT发现Arena Chunk分配资源很高(该NMT数据来源Stackoverflow)。

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) 

原因

anonAnonymous memory段的缩写。

Anonymous memory的使用会使虚拟内存(VIRT)、物理内存(RSS)使用率上升。

Java 8开始使用metaspace原空间取代永久代,而元空间是存放在操作系统本地内存中,每个线程都会使用元空间,每个线程都分配一个arena,每个都是64MB,就会导致巨大的虚拟地址被分配。

glibc 2.11

glibc 2.11(为应用系统在多核心CPU和多Sockets环境中高伸缩性提供了一个动态内存分配的特性增强)版本开始引入了per thread arena内存池,Native Heap区被打散为sub-pools,这部分内存池叫做Arena内存池。

解决方法

设置MALLOC_ARENA_MAX=1

export MALLOC_ARENA_MAX=1

相关文档

MALLOC_ARENA_MAX=1 does not work in RHEL 6.2: https://bugzilla.redhat.com/show_bug.cgi?id=799327

Views: 211 · Posted: 2023-12-20

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh