gpt4 book ai didi

java - JVM 中不断增长的常驻大小集

转载 作者:行者123 更新时间:2023-12-01 14:03:51 32 4
gpt4 key购买 nike

我有一个在 64 位 LINUX 上运行的 JAVA 进程,版本为“CentOS Linux 版本 7.3.1611”,RAM 为 7.6GB。
下面是一些使用过的 JVM 标志,

  • -Xmx3500m
  • -Xms3500m
  • -XX:MaxMetaspaceSize=400m
  • -XX:CompressedClassSpaceSize=35m

  • 注意:线程栈(1MB)和代码缓存(240MB)的大小为默认值,JDK版本为1.8.0_252。
    在运行 TOP 命令时,它观察到我的 6.3 GB RAM 由 java
    过程。
    PR   NI    VIRT     RES    SHR S  %CPU %MEM   TIME+   COMMAND   
    20 0 28.859g 6.341g 22544 S 215.2 83.1 4383:23 java
    我尝试使用 JCMD、JMAP 和 JSTAT 命令分析 JVM 的 native 内存。
    JMAP -heap 命令的输出:
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.252-b14

    using thread-local object allocation.
    Garbage-First (G1) GC with 33 thread(s)

    Heap Configuration:
    MinHeapFreeRatio = 40
    MaxHeapFreeRatio = 70
    MaxHeapSize = 3670016000 (3500.0MB)
    NewSize = 1363144 (1.2999954223632812MB)
    MaxNewSize = 2202009600 (2100.0MB)
    OldSize = 5452592 (5.1999969482421875MB)
    NewRatio = 2
    SurvivorRatio = 8
    MetaspaceSize = 21807104 (20.796875MB)
    CompressedClassSpaceSize = 36700160 (35.0MB)
    MaxMetaspaceSize = 419430400 (400.0MB)
    G1HeapRegionSize = 1048576 (1.0MB)

    Heap Usage:
    G1 Heap:
    regions = 3500
    capacity = 3670016000 (3500.0MB)
    used = 1735444208 (1655.048568725586MB)
    free = 1934571792 (1844.951431274414MB)
    47.28710196358817% used
    G1 Young Generation:
    Eden Space:
    regions = 1311
    capacity = 2193620992 (2092.0MB)
    used = 1374683136 (1311.0MB)
    free = 818937856 (781.0MB)
    62.66730401529637% used
    Survivor Space:
    regions = 113
    capacity = 118489088 (113.0MB)
    used = 118489088 (113.0MB)
    free = 0 (0.0MB)
    100.0% used
    G1 Old Generation:
    regions = 249
    capacity = 1357905920 (1295.0MB)
    used = 241223408 (230.04856872558594MB)
    free = 1116682512 (1064.951431274414MB)
    17.76436824135799% used

    485420 interned Strings occupying 83565264 bytes.
    JSTAT -gc 命令的输出:
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    0.0 33792.0 0.0 33792.0 1414144.0 1204224.0 2136064.0 1558311.7 262872.0 259709.5 19200.0 18531.5 22077 985.995 10 41.789 1027.785
    0.0 33792.0 0.0 33792.0 1414144.0 1265664.0 2136064.0 1558823.7 262872.0 259709.5 19200.0 18531.5 22077 985.995 10 41.789 1027.785
    0.0 63488.0 0.0 63488.0 124928.0 32768.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
    0.0 63488.0 0.0 63488.0 124928.0 49152.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
    0.0 63488.0 0.0 63488.0 124928.0 58368.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
    甚至 的输出产生的总和“JCMD pid VM.native_memory 摘要”大约是 5.0GB,甚至不接近 6.3GB。所以我找不到余额 1.3GB 的用途。
    我试图找出 6.3GB 是如何与 JVM 实际映射的。所以我决定检查/proc/pid 文件夹。
    在/proc/pid/status 文件中,
    VmRSS   : 6649680 kB 
    RssAnon : 6627136 kB
    RssFile : 22544 kB
    RssShmem: 0 kB
    由此我发现6.3GB空间大部分都被匿名空间占用了。
    PMAP 命令的输出(截断):
    Address           Kbytes     RSS   Dirty Mode  Mapping
    0000000723000000 3607296 3606076 3606076 rw--- [ anon ]
    00000007ff2c0000 12544 0 0 ----- [ anon ]
    00007f4584000000 132 4 4 rw--- [ anon ]
    00007f4584021000 65404 0 0 ----- [ anon ]
    00007f4588000000 132 12 12 rw--- [ anon ]
    00007f4588021000 65404 0 0 ----- [ anon ]
    00007f458c000000 132 4 4 rw--- [ anon ]
    00007f458c021000 65404 0 0 ----- [ anon ]
    00007f4590000000 132 4 4 rw--- [ anon ]
    00007f4590021000 65404 0 0 ----- [ anon ]
    00007f4594000000 132 8 8 rw--- [ anon ]
    00007f4594021000 65404 0 0 ----- [ anon ]
    00007f4598000000 132 4 4 rw--- [ anon ]
    00007f4598021000 65404 0 0 ----- [ anon ]
    00007f459c000000 2588 2528 2528 rw--- [ anon ]

    我发现第一个匿名地址可能映射到堆内存,因为它的大小为 3.4GB。但是,我无法找到匿名空间的其余部分是如何使用的。
    我需要帮助找出 JVM 进程如何使用额外的 1.3 GB。
    除了 native 内存跟踪中提到的之外,任何有关 JVM 使用的内存的信息都将不胜感激。

    最佳答案

    正如所讨论的 here ,除了 Native Memory Tracking 覆盖的区域,JVM 进程中还有其他消耗内存的东西。
    许多大小正好为 64MB 的匿名区域(如您的 pmap 输出中)表明这些是 malloc arenas .已知标准 glibc 分配器具有 issues内存使用过多,尤其是在具有许多线程的应用程序中。我建议使用 jemalloc (或 tcmallocmimalloc )作为标准分配器的替代品 - 它没有提到的泄漏。另一种解决方案是使用 MALLOC_ARENA_MAX 限制 malloc arenas 的数量。环境变量。
    如果切换到 jemalloc 后问题仍然存在,这很可能是 native 内存泄漏的迹象。例如,Java 应用程序中的 native 泄漏可能是由

  • 未关闭的资源/流:ZipInputStream , DirectoryStream , Inflater , Deflater
  • JNI 库和代理库,包括标准 jdwp代理
  • improper bytecode instrumentation

  • 要查找泄漏源,您也可以使用 jemalloc其内置 profiling feature .然而, jemalloc无法展开 Java 堆栈跟踪。
    async-profiler可以显示混合的 Java+ native 堆栈。虽然它的主要目的是 CPU 和分配分析,但 async-profiler 也可以帮助 find native memory leaks在 Java 应用程序中。
    有关详细信息和更多示例,请参阅我的 Memory Footprint of a Java Process介绍。

    关于java - JVM 中不断增长的常驻大小集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63699573/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com