`

Java 进程占用 VIRT 虚拟内存超高的问题

阅读更多

1. 现象

最近发现线上机器 java 8 进程的 VIRT 虚拟内存使用达到了 11G+



 
2. 不管用的 -Xmx

首先第一想到的当然使用 java -Xmx 去限制堆的使用。但是无论怎样设置,都没有什么效果。没办法,只好开始苦逼的研究。

 

3. 什么是 VIRT

现代操作系统里面分配虚拟地址空间操作不同于分配物理内存。在64位操作系统上,可用的最大虚拟地址空间有16EB,即大概180亿GB。那么在一台只有16G的物理内存的机器上,我也能要求获得4TB的地址空间以备将来使用。例如:

    void *mem = mmap(0, 4ul * 1024ul * 1024ul * 1024ul * 1024ul,

                     PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,

                     -1, 0);

 

当使用 mmap 并设置 MAP_NORESERVE 标志时,并不会要求实际的物理内存和swap空间存在。所以上述代码可以在top中看到使用了 4096g VIRT 虚拟内存,这当然是不可能的,它只是表示使用了 4096GB 的地址空间而已。

 

4. 为什么会用这么多地址空间

Java 程序为什么会使用这么多的地址空间呢?使用“pmap -x”来查看一下:

00007ff638021000   65404       0       0 -----    [ anon ]

00007ff63c000000     132      36      36 rw---    [ anon ]

00007ff63c021000   65404       0       0 -----    [ anon ]

00007ff640000000     132      28      28 rw---    [ anon ]

00007ff640021000   65404       0       0 -----    [ anon ]

00007ff644000000     132       8       8 rw---    [ anon ]

00007ff644021000   65404       0       0 -----    [ anon ]

00007ff648000000     184     184     184 rw---    [ anon ]

00007ff64802e000   65352       0       0 -----    [ anon ]

00007ff64c000000     132     100     100 rw---    [ anon ]

00007ff64c021000   65404       0       0 -----    [ anon ]

00007ff650000000     132      56      56 rw---    [ anon ]

00007ff650021000   65404       0       0 -----    [ anon ]

00007ff654000000     132      16      16 rw---    [ anon ]

00007ff654021000   65404       0       0 -----    [ anon ]

发现有很多奇怪的64MB的内存映射,查资料发现这是 glibc 在版本 2.10 引入的 arena 新功能导致。CentOS 6/7 glibc 大都是 2.12/ 2.17 了,所以都会有这个问题。这个功能对每个线程都分配一个分配一个本地arena来加速多线程的执行。

glibc arena.c 中使用的 mmap() 调用就和之前的示例代码类似:

    p2 = (char *)mmap(aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,

                          MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)

之后,只有很小的一部分地址被映射到了物理内存中:

    mprotect(p2, size, PROT_READ | PROT_WRITE)

因此在一个多线程程序中,会有相当多的 64MB arena 被分配。这个可以用环境变量 MALLOC_ARENA_MAX 来控制。在64位系统中的默认值为 128

5. Java 的特殊性

Java 程序由于自己维护堆的使用,导致调用 glibc 去管理内存的次数较少。更糟的是 Java 8 开始使用 metaspace 原空间取代永久代,而元空间是存放在操作系统本地内存中,那线程一多,每个线程都要使用一点元空间,每个线程都分配一个 arena,每个都64MB,就会导致巨大的虚拟地址被分配。

6. 结束语

总结一下:

<!--[if !supportLists]-->·         <!--[endif]-->VIRT高是因为分配了太多地址空间导致。

<!--[if !supportLists]-->·         <!--[endif]-->一般来说不用太在意VIRT太高,因为你有16EB的空间可以使用。

 

<!--[if !supportLists]-->·         <!--[endif]-->如果你实在需要控制VIRT的使用,设置环境变量MALLOC_ARENA_MAX,例如hadoop推荐值为4,因为YARN使用VIRT值监控资源使用。

 

y原源文地址:http://www.cnblogs.com/seasonsluo/p/java_virt.html

 

 

  • 大小: 22.5 KB
分享到:
评论

相关推荐

    查看LINUX进程内存占用情况.docx

    * VIRT:进程占用的虚拟内存 * RES:进程占用的物理内存 * SHR:进程使用的共享内存 * S:进程的状态。S 表示休眠,R 表示正在运行,Z 表示僵死状态,N 表示该进程优先值为负数 * %CPU:进程占用 CPU 的使用率 * %...

    Virt-manager虚拟化技术介绍.pdf

    实验9 使用Virt-install安装虚拟机并使用Virt-viewer连接桌面,实验目的包括掌握virt-install的常用参数及安装,掌握virt-viewer的使用及安装,掌握使用virt-install安装虚拟机。 实验10 使用virt-manager创建...

    查看LINUX进程内存占用情况

    * VIRT:进程占用的虚拟内存 * RES:进程占用的物理内存 * SHR:进程使用的共享内存 * S:进程的状态。S 表示休眠,R 表示正在运行,Z 表示僵死状态,N 表示该进程优先值为负数 * %CPU:进程占用 CPU 的使用率 * %...

    linux进程内存占用排序命令.pdf

    在给出的示例中,可以看到`top`命令默认显示的信息包括:PID(进程ID)、USER(用户)、PR(优先级)、NI(Nice值)、VIRT(虚拟内存大小)、RES(物理内存占用)、SHR(共享内存)、S(状态)、%CPU(CPU使用率)、...

    Linux查看进程的内存占用情况.pdf

    5. VIRT:进程占用的虚拟内存总量,包括共享库、堆栈和交换空间。 6. RES:进程占用的物理内存,不包括交换空间。 7. SHR:进程使用的共享内存大小。 8. S:进程状态,如S(休眠)、R(运行)、Z(僵尸)和N(负...

    Virt-manager虚拟化技术介绍.pptx

    Virt-manager 虚拟化技术介绍 virt-manager 是虚拟机管理器(Virtual Machine Manger)的缩写,也是该管理工具的软件包名称。virt-manager 是用于管理虚拟机的图形化的桌面用户接口,目前仅支持在 Linux 或其他类 ...

    Linux中的top, htop资源管理器命令中的VIRT列和RES列的区别

    Linux中的top, htop资源管理器命令中的VIRT列和RES列的...Linux运维都知道,VIRT是虚拟内存,RES是物理内存 但是如何在VIRT中申请内存,如何在RES中申请内存,你知道吗?你以为只是malloc,new这么简单吗? 奉上我作的实验总结

    Linux查看进程的内存占用情况

     VIRT:进程占用的虚拟内存  RES:进程占用的物理内存  SHR:进程使用的共享内存  S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数  %CPU:进程占用CPU的使用率  %...

    bus-virt-phys-mapping总线_虚拟_物理地址映射1

    在计算机系统中,内存地址映射是一个至关重要的概念,它涉及到CPU、虚拟内存以及设备之间的交互。本篇文章将深入探讨“bus-virt-phys-mapping”主题,即总线、虚拟和物理地址映射,主要关注在Linux环境下的PCI DMA...

    查看Linux进程占用的资源.docx

    在`top`的进程列表中,每一列都有特定含义,如PID(进程ID)、USER(进程所有者)、%CPU(CPU占用率)、%MEM(内存占用率)、VIRT(虚拟内存大小)、RSS(物理内存大小)、COMMAND(进程命令)。这些信息可以帮助...

    phys_virt:物理内存发现。 这是一个 Winblows 内核驱动程序,可帮助将物理内存地址转换为它们各自的虚拟内存地址(即将物理页面映射到用户模式进程虚拟地址空间)

    phys_to_virt 一个简单的 Windows 驱动程序,用于将(或“映射”)物理内存地址转换为调用进程虚拟地址空间。 这将很快支持更多操作。 包含一个用户模式应用程序来演示如何使用它。关于这主要是为了教育目的和发现。...

    KVM虚拟机管理(使用virt-manager和virsh)

    KVM虚拟机管理(使用virt-manager和virsh) 本文将详细介绍KVM虚拟机管理,包括Libvirt管理架构、使用virt-manager管理虚拟机和使用virsh管理虚拟机。 一、Libvirt管理架构 Libvirt是一个开源的虚拟机管理工具和...

    Linux查看CPU和内存使用情况.pdf

    - `VIRT`: 进程占用的虚拟内存 - `RES`: 进程占用的物理内存 - `SHR`: 进程使用的共享内存 - `S`: 进程状态,如休眠(S)、运行(R)、僵死(Z) - `%CPU`: 进程占用的CPU使用率 - `%MEM`: 进程使用的物理内存占总...

    virt-manager1.0

    2. **实时监控**:virt-manager 提供实时性能监控图表,包括 CPU 使用率、内存占用、磁盘 I/O 和网络流量等,帮助管理员了解虚拟机运行状态。 3. **远程管理**:除了本地虚拟机,virt-manager 还允许用户通过 SSH ...

    Linux查看CPU和内存使用情况.docx

    5. **VIRT**: 进程占用的虚拟内存总量。 6. **RES**: 进程占用的物理内存。 7. **SHR**: 进程使用的共享内存。 8. **%CPU**: 进程占用的CPU使用率。 9. **%MEM**: 进程占用的内存使用率。 10. **TIME+**: 进程自启动...

    memory虚拟内存.txt1

    本文档由Russell King撰写,专注于解释Linux内核在ARM处理器上的虚拟内存布局,包括哪些区域可供平台使用,哪些区域被通用代码占用。 首先,从ffff8000到ffffffff的区域用于`copy_user_page`和`clear_user_page`...

    virt2phys内核驱动安装与下载

    virt2phys内核驱动是Linux操作系统中用于获取虚拟地址对应的物理地址的一个工具,它在系统调试、性能分析以及内存管理等方面有着重要的应用。在本文中,我们将深入探讨virt2phys驱动的安装、下载过程,以及它与C++...

    virt-manager-0.8.4.tar

    9. **监控和日志**:virt-manager提供性能监控功能,可以查看虚拟机的CPU、内存、磁盘I/O等资源使用情况,帮助用户了解虚拟机的运行状态,并记录相关日志。 在【压缩包子文件的文件名称列表】中,只有一个名为"virt...

Global site tag (gtag.js) - Google Analytics