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

一、现象说明

最近发现线上机器java 7(openjdk)进程的 VIRT 虚拟内存使用达到了 50G+,如下所示:

PID      USER  PR NI     VIRT  RES    SHR     S   %CPU   %MEM    TIME+    COMMAND
3130    tomcat  20  0    9128m  1.4g   6544    S    1.3   9.0    84:14.67  java
31480   tomcat  20  0    7244m  983m   5528    S    0.3   6.2     34:36.95  java
22142   tomcat  20  0    6787m   537m   13m     S    0.7   3.4     6:26.70   java
22097   tomcat  20  0    7049m   515m   11m    S     0.3  3.2     4:52.39   java
1975    root    20  0    600m    10m    1560   S     0.0  0.1     2:50.42   salt-minion

根据现象猜测:

1. 可能出现内存不足,使用了较多的swap内存;

2. java jdk的版本导致;

3. 由于是虚拟机可能出现物理主机内存不足,导致虚拟机伪内存资源;

二、问题排查

2.1 不管用 xms

首先第一想到的当然使用 java 的-Xmx去限制堆的使用。然而通过top查看,其实并没有使用多少物理内存。

2.2 通过vmstate查看分析

[[email protected] ~]# vmstat -a -S M
procs      -----------memory----------    ---swap--     -----io----    --system--     -----cpu-----
r  b    swpd   free   inact  active     si   so        bi     bo       in     cs       us sy id  wa st
0 0     81     1604   340    3381       0    0         1       1       6      15       0   0 100  0  0

从上面的信息,可以看出来其实资源使用实际很少;

2.3 排查虚拟机资源是否消耗

经过查看vmware,发现上面的虚拟机资源使用并无异常。

三、确定问题原因

经过查阅资料,偶然间发现,这属于一个正常的现象,为什么正常呢?请看下面分析。

glibc 在版本 2.10 引入的 arena 新功能导致。CentOS 6/7 的 glibc 大都是 2.12/ 2.17 了,所以都会有这个问题。这个功能对每个线程都分配一个分配一个本地arena来加速多线程的执行。Java 程序由于自己维护堆的使用,导致调用 glibc 去管理内存的次数较少。更糟的是 Java 8 开始使用 metaspace 原空间取代永久代,而元空间是存放在操作系统本地内存中,那线程一多,每个线程都要使用一点元空间,每个线程都分配一个 arena,每个都64MB,就会导致巨大的虚拟地址被分配。

总结如下:

  • VIRT高是因为分配了太多地址空间导致。
  • 一般来说不用太在意VIRT太高,因为你有更多的空间可以使用。
  • 如果你实在需要控制VIRT的使用,设置环境变量MALLOC_ARENA_MAX,例如hadoop推荐值为4,因为YARN使用VIRT值监控资源使用。

参考链接:https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

 

时间: 2024-12-29 10:54:23

Java 进程占用 VIRT 虚拟内存超高的问题研究的相关文章

Java虚拟机六:Java进程占用cpu过高问题分析

在平时开发过程中,经常会碰到Java进程占用cpu过高的现象,本篇将简单记录一下自己分析该类问题的步骤. 1.使用 top -p <pid> 命令(<pid>为Java进程的id号)查看Java进程的cpu占用: 该Java进程占用cpu达到92.2%. 2.使用 top -Hp <pid>  命令(<pid>为Java进程的id号)查看该Java进程内所有线程的资源占用情况(按shft+p按照cpu占用进行排序,按shift+m按照内存占用进行排序)此处按

linux下查找java进程占用CPU过高原因

1. 查找进程 top查看进程占用资源情况 明显看出java的两个进程22714,12406占用过高cpu. 2.查找线程 使用top -H -p <pid>查看线程占用情况 3.查找java的堆栈信息 将线程id转换成十六进制 #printf %x 15664 #3d30 然后再使用jstack查询线程的堆栈信息 语法:jstack <pid> | grep -a 线程id(十六进制) jstack <pid> | grep -a 3d30 这样就找出了有问题的代码了

Java 进程占用内存过多,幕后元凶原来是线程太多

那天中午吃饭,一个同事说,那个项目组的人快气死我了,程序有问题,早晨在群里@了他们,到中午才回消息,然后竟然还说他们的程序没有问题,是我们这边调用的太频繁了. 简直想笑. 背景说明 我们当前这个系统和很多的第三方系统做了集成,出问题的就是其中一个三方系统.其实很简单,他们的系统会产生一些个人待办任务,然后待办任务的个数需要推送到我们的 APP 上,作为图标的角标显示. 用户数据已经打通,其实很简单的需求,角标通知也不要求实时,10分钟刷一次就可以.这个场景非常典型,用消息队列再合适不过了.他们把

java进程占用cpu过高分析是哪些线程

拿hbase基准测试列子来分析哪些线程使用比较高的cpu,环境是linux,基准测试命令: hbase org.apache.hadoop.hbase.PerformanceEvaluation  --rows=500000 --nomapred --presplit=5 --writeToWAL=true randomWrite 5 首先查看占用cpu最高的进程和线程id,执行命令: [[email protected] logs]$ ps Hh -eo pid,tid,pcpu | sort

生产环境下JAVA进程高CPU占用故障排查

问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过,排除此类情况.2,程序代码有问题,出现死循环,可能性极大. 问题解决:1,开发那边无法排查代码某个模块有问题,从日志上也无法分析得出.2,记得原来通过strace跟踪的方法解决了一台PHP服务器CPU占用高的问题,但是通过这种方法无效,经过google搜索,发现可以通过下面的方法进行解决,那就尝试下

查看进程占用的内存情况

可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看java用户的进程内存使用情况的话可以使用如下的命令: (1)top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看tomcat用户的进程内存使用情况的话可以使用如下的命令: $ top -u tomcat 内容解释: PID:进程的ID    US

Linux中查看进程占用内存和系统资源情况的命令

用 'top -i' 看看有多少进程处于 Running 状态,可能系统存在内存或 I/O 瓶颈,用 free 看看系统内存使用情况,swap 是否被占用很多,用 iostat 看看 I/O 负载情况... 还有一种办法是 ps -ef | sort -k7 ,将进程按运行时间排序,看哪个进程消耗的cpu时间最多. top: 主要参数 d:指定更新的间隔,以秒计算. q:没有任何延迟的更新.如果使用者有超级用户,则top命令将会以最高的优先序执行. c:显示进程完整的路径与名称. S:累积模式,

Linux下如何查看哪些进程占用的CPU内存资源最多

linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下获取占用内存资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head 命令组合解析(针对CPU的,MEN也同样道理): ps aux|head -1;ps aux|grep -v PID|sort -rn -k

Linux下java进程CPU占用率高分析方法

Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 1. 通过top命令找到可疑进程PID top - 09:37:18 up 70 days, 16:29, 2 users, load average: 1.13, 1.04, 0.97 Tasks: 105 total, 1 running