JVM进程如何分配内存? [英] How does a JVM process allocate its memory?

查看:181
本文介绍了JVM进程如何分配内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a little gap in understanding how a JVM process allocates its own memory. As far as I know

RSS = Heap size + MetaSpace + OffHeap size

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

where OffHeap consists of thread stacks, direct buffers, mapped files (libraries and jars) and JVM code itself;

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

At the moment I’m trying to analyze my Java application (Spring Boot + Infinispan) which RSS is 779M (it runs in a docker container, so pid 1 is ok):

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

根据 jvisualvm ,已提交堆大小 374M

According to jvisualvm, committed Heap size is 374M

Metasapce尺寸 89M

Metasapce size is 89M

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

In other words, I want to explain 799M - (374M + 89M) = 316M of OffHeap memory.

我的应用程序(平均) 36个活动线程

My app has (in average) 36 live threads.

每个线程消耗1M:

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

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

So, here we can add 36M.

应用程序使用DirectBuffer的唯一地方是NIO。据JMX所见,它不会消耗大量资源 - 只有 98K

The only place where the app uses DirectBuffer is NIO. As far as I can see from JMX, it doesn’t consume a lot of resources - only 98K

最后一步是映射libs和jar。但根据 pmap 完整输出

The last step is mapped libs and jars. But according to pmap (full output)

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

12896K

plus

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

9720K

我们这里只有 20M

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

Hence, we still have to explain 316M - (36M + 20M) = 260M :(

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

Does anyone have any idea what I missed?

推荐答案

方法:

您可能想要使用 Java HotSpot本机内存跟踪(NMT)

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

This may give you an exact list of memory allocated by the JVM, splitted up into the different areas heap, classes, threads, code, GC, compiler, internal, symbols, memory tracking, pooled free chunks, and unknown.

用法


  • 您可以使用 -XX:NativeMemoryTracking = summary 启动您的应用程序。

可以使用 jcmd< pid>完成对当前堆的观察。 VM.native_memory摘要

在哪里可以找到jcmd / pid

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

On a default OpedJDK installation on Ubuntu this can be found at /usr/bin/jcmd.

只需运行 jcmd 而不带任何参数,就可以获得正在运行的Java应用程序列表。

By just running jcmd without any parameter, you get a list of running Java applications.

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

输出

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

You will then receive a complete overview over your heap, looking something like the following:


总计:保留= 664192KB,已提交= 253120KB< ---本机内存跟踪跟踪的总内存

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


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

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

(mmap:reserved = 5 16096KB,已提交= 204800KB)

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

(保留= 6568KB,已提交= 4140KB)< ---类元数据

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

(类#665)< ---已加载类的数量

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

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

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

(mmap:reserved = 6144KB,已提交= 3716KB)

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

线程(保留= 6868KB,已提交= 6868KB)
(线程#15)< ---线程数

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

(堆栈:保留= 6780KB,已提交= 6780KB)< ---线程堆栈使用的内存

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

(malloc = 27KB,#66 )

(malloc=27KB, #66)

(竞技场= 61KB,#30)< ---资源和处理区域

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

代码(保留= 102414KB,已提交= 6314KB)

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

(malloc = 2574KB,#74316)

(malloc=2574KB, #74316)

(mmap:reserved = 99840KB,已提交= 3740KB)

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

GC (保留= 26154KB,已提交= 24938KB)

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

(malloc = 486KB,#110)

(malloc=486KB, #110)

(mmap:保留= 25668KB,承诺= 24452KB)

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

编译器(保留= 106KB,承诺= 106KB)

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

(malloc = 7KB,#90)

(malloc=7KB, #90)

(竞技场= 99KB,#3)

(arena=99KB, #3)

内部(保留= 586KB,承诺= 554KB)

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

(malloc = 554KB,#1677)

(malloc=554KB, #1677)

(mmap:reserved = 32KB ,承诺= 0KB)

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

符号(保留= 906KB,承诺= 906KB)

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

(malloc = 514KB,#2736)

(malloc=514KB, #2736)

(竞技场= 392KB,#1)

(arena=392KB, #1)

内存跟踪(保留= 3184KB,已提交= 3184KB)

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

(malloc = 3184KB,#300)

(malloc=3184KB, #300)

汇总免费大块(保留= 1276KB,承诺= 1276KB)

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

(malloc = 1276KB)

(malloc=1276KB)

未知(保留= 33KB,承诺= 33KB)

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

(竞技场= 33KB,#1)

(arena=33KB, #1)

这详细介绍了JVM使用的不同内存区域,以及还会显示保留提交内存。

This gives a detailed overview of the different memory areas used by the JVM, and also shows the reserved and commited memory.

我不知道哪种技术可以为您提供更多内容详细的记忆消费清单。

I don't know of a technique that gives you a more detailed memory consumption list.

进一步阅读:

您还可以使用 -XX:NativeMemoryTracking = detail 与其他 jcmd 命令组合使用。可以在 Java Platform中找到更详细的说明,标准版故障排除指南 - 2.6 jcmd实用程序。您可以通过jcmd< pid> help检查可能的命令

You can also use -XX:NativeMemoryTracking=detail in combination with further jcmd commands. A more detailed explaination can be found at Java Platform, Standard Edition Troubleshooting Guide - 2.6 The jcmd Utility. You can check possible commands via "jcmd <pid> help"

这篇关于JVM进程如何分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆