有台Linux主机内存很奇怪,主要是VIRT和DATA过高,SWAP几乎没有
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP DATA COMMAND 797 root 20 0 0 0 0 S 6.9 0.0 53:49.97 0 0 vmmemctl 29065 aicrm 20 0 3065m 148m 17m S 3.6 0.2 5:08.12 0 2.9g java 25975 aicrm 20 0 3065m 162m 17m S 3.3 0.3 5:01.36 0 2.9g java 23815 aicrm 20 0 2480m 139m 17m S 2.9 0.2 2:48.43 1888 2.3g java 26731 aicrm 20 0 3065m 191m 17m S 2.9 0.3 5:13.41 0 2.9g java 28145 aicrm 20 0 3065m 159m 17m S 2.9 0.2 5:24.85 0 2.9g java 28657 aicrm 20 0 3065m 159m 17m S 2.9 0.2 5:05.77 0 2.9g java 26150 aicrm 20 0 3065m 168m 17m S 2.6 0.3 5:09.91 0 2.9g java 27861 aicrm 20 0 3065m 153m 17m S 2.6 0.2 5:10.44 0 2.9g java
我在网上学习到 VIRT=SWAP+RES,也找到其他主机自认为正常的显示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP DATA COMMAND 20715 aicrm 21 0 683m 179m 17m S 51.8 0.3 81:27.57 503m 585m java 14048 aiucp 24 0 661m 100m 15m S 37.6 0.2 66:01.16 561m 565m java 14047 aiucp 15 0 3872 548 420 S 3.6 0.0 4:24.97 3324 328 cronolog 14158 aiucp 23 0 674m 167m 15m S 3.0 0.3 3:16.35 507m 578m java 20713 aicrm 15 0 3872 560 420 R 2.3 0.0 4:59.21 3312 328 cronolog 22640 aicrm 18 0 745m 156m 17m S 1.6 0.2 1:35.87 589m 647m java 22274 aicrm 19 0 670m 148m 17m S 1.3 0.2 1:10.18 521m 572m java 24631 aicrm 19 0 670m 133m 17m S 1.3 0.2 1:10.54 536m 572m java
上下两台主机的启动参数内存分配的一样
内核分别是
2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
2.6.18-238.el5 #1 SMP Thu Jan 13 15:51:15 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
为什么有这么大的差异,请大神帮忙分析分析
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 的地址空间而已。
使用“pmap -x”来查看可以发现Java 程序每个线程都分配一个分配一个本地arena来加速多线程的执行。每个都64MB,就会导致巨大的虚拟地址被分配。
如果你实在需要控制VIRT的使用,设置环境变量MALLOC_ARENA_MAX,例如hadoop推荐值为4,因为YARN使用VIRT值监控资源使用。
DATA段占用较高,是不是你程序里的数据都缓存起来了,没有释放。
建议你重启下进程,然后配合日志观察内存是否在一段时间内攀升,然后查看期间程序操作了什么。
如果排除是程序BUG,那么可以修改下GC策略试试。
程序都是完全一样的,没问题。可以看到RES 两者都是差不多的,我想知道VIRT 与什么有关,对主机性能有没有影响
@鼠标疯子:
VIRT = SWAP + RES
RES = CODE + DATA
出自top的man手册。