gpt4 book ai didi

java - JVM 进程如何分配内存?

转载 作者:IT王子 更新时间:2023-10-28 23:54:58 27 4
gpt4 key购买 nike

我在理解 JVM 进程如何分配自己的内存方面有一点差距。据我所知

RSS = Heap size + MetaSpace + OffHeap size

其中 OffHeap 由线程堆栈、直接缓冲区、映射文件(库和 jar)和 JVM 代码本身组成;

目前我正在尝试分析我的 Java 应用程序(Spring Boot + Infinispan),RSS 为 779M(它在 docker 容器中运行,所以 pid 1 可以):

[ root@daf5a5ae9bb7:/data ]$ ps -o rss,vsz,sz 1
RSS VSZ SZ
798324 6242160 1560540

根据jvisualvm,提交的堆大小为374M enter image description here

元空间大小为89M
enter image description here

换句话说,我想解释一下799M - (374M + 89M) = 316M OffHeap内存。

我的应用有(平均)36 个 Activity 线程enter image description here

这些线程中的每一个消耗 1M:

[ root@fac6d0dfbbb4:/data ]$ java -XX:+PrintFlagsFinal -version |grep ThreadStackSize    
intx CompilerThreadStackSize = 0
intx ThreadStackSize = 1024
intx VMThreadStackSize = 1024

所以,这里我们可以添加36M

应用程序使用 DirectBuffer 的唯一地方是 NIO。据我从 JMX 可以看出,它并没有消耗很多资源——只有 98K enter image description here

最后一步是映射库和 jar 。但是根据 pmap ( full output )

[ root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep ".so.*" | awk '{ sum+=$3} END {print sum}'

12896K

加上

root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep “.jar" | awk '{ sum+=$3} END {print sum}'

9720K

我们这里只有 20M

因此,我们还是要解释316M - (36M + 20M) = 260M :(

有人知道我错过了什么吗?

最佳答案

方法:

您可能想使用 Java HotSpot Native Memory Tracking (NMT) .

这可能会为您提供 JVM 分配的内存的确切列表,分为不同的区域堆、类、线程、代码、GC、编译器、内部、符号、内存跟踪、池化空闲 block ,未知

用法:

  • 您可以使用 -XX:NativeMemoryTracking=summary 开始您的应用程序.

  • 可以用jcmd <pid> VM.native_memory summary观察当前堆。 .

在哪里可以找到 jcmd/pid:

在 Ubuntu 上的默认 OpedJDK 安装中,可以在 /usr/bin/jcmd 找到它.

只需运行 jcmd如果没有任何参数,您将获得正在运行的 Java 应用程序的列表。

user@pc:~$ /usr/bin/jcmd
5169 Main <-- 5169 is the pid

输出:

然后您将收到堆的完整概览,如下所示:

Total: reserved=664192KB, committed=253120KB <--- total memory tracked by Native Memory Tracking

  • Java Heap (reserved=516096KB, committed=204800KB) <--- Java Heap

    (mmap: reserved=516096KB, committed=204800KB)

  • Class (reserved=6568KB, committed=4140KB) <--- class metadata

    (classes #665) <--- number of loaded classes

    (malloc=424KB, #1000) <--- malloc'd memory, #number of malloc

    (mmap: reserved=6144KB, committed=3716KB)

  • Thread (reserved=6868KB, committed=6868KB) (thread #15) <--- number of threads

    (stack: reserved=6780KB, committed=6780KB) <--- memory used by thread stacks

    (malloc=27KB, #66)

    (arena=61KB, #30) <--- resource and handle areas

  • Code (reserved=102414KB, committed=6314KB)

    (malloc=2574KB, #74316)

    (mmap: reserved=99840KB, committed=3740KB)

  • GC (reserved=26154KB, committed=24938KB)

    (malloc=486KB, #110)

    (mmap: reserved=25668KB, committed=24452KB)

  • Compiler (reserved=106KB, committed=106KB)

    (malloc=7KB, #90)

    (arena=99KB, #3)

  • Internal (reserved=586KB, committed=554KB)

    (malloc=554KB, #1677)

    (mmap: reserved=32KB, committed=0KB)

  • Symbol (reserved=906KB, committed=906KB)

    (malloc=514KB, #2736)

    (arena=392KB, #1)

  • Memory Tracking (reserved=3184KB, committed=3184KB)

    (malloc=3184KB, #300)

  • Pooled Free Chunks (reserved=1276KB, committed=1276KB)

    (malloc=1276KB)

  • Unknown (reserved=33KB, committed=33KB)

    (arena=33KB, #1)

这给出了 JVM 使用的不同内存区域的详细概述,还显示了保留提交内存。

我不知道有什么技术可以为您提供更详细的内存消耗列表。

进一步阅读:

您还可以使用 -XX:NativeMemoryTracking=detail结合进一步 jcmd命令。可以在 Java Platform, Standard Edition Troubleshooting Guide - 2.6 The jcmd Utility 找到更详细的解释。 .您可以通过 "jcmd <pid> help" 检查可能的命令

关于java - JVM 进程如何分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35502348/

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