Linux下java VIRT占用较高

本文以阿里云1核2G服务器安装Java后内存占用高为例,介绍了查看内存占用的命令,如top、ps aux、free等。解释了RSS列表示程序占用物理内存,VIRT列表示虚拟内存。还说明了Linux内存机制,指出ps aux中RSS值不能真实反映物理内存使用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,不用在意。

 

阿里云的服务器,1核2G,安装java后发现内存占用1.7G/2G,top命令查看进程,发现java占用内存极高,甚至多于20G。

去网上查了原因,以下为部分答案:

RSS列 表示, 程序占用了多少物理内存。 虚拟内存可以不用考虑,它并不占用实际物理内存。

 top 命令也可以 其中VIRT(或VSS)列 表示,程序占用了多少虚拟内存。 同 ps aux 中的 VSZ列 RES列 表示, 程序占用了多少物理内存。同 ps aux 中的RSS列

在linux下, 查看当前系统占用了多少内存, 一般的命令是 free其中, free就是系统还有多少内存可以使用。但由于 linux 系统对内存使用有一个原则, 就是, 内存是宝贵的, 能使用多少就使用多少。 所以, linux会把已经调用过的包缓存起来,放在内存里。这样,实际上,可以使用的内存,就可以理解为, free+buffers+cached

当你了解完这些命令以后, 再去使用ps aux 命令去查看的时候, 会发现一个奇怪的现象。 所有的 RSS 列的数据,加起来, 比物理内存的数要大很多。 比如, 物理内存为2G, 而RSS列的数据加起来,可能有5个G之多, 这是怎么回事了? 这是因为RSS列的值骗了我们。 linux的内存机制是这样的: 在运行一个程序时, linux会调用该程序依赖的链接库, 如lib.xx.so。 首先看该链接库是否被映射进内存中,如果没有被映射,则将代码段与数据段映射到内存中,否则只是将其加入进程的地址空间。 这样,当N个程序,依赖到lib.xx.so的时候, 实际上,内存中只有一个lib.xx.so ,而不是N个。 而RSS在显示一个程序占用的实际物理内存时, 将lib.xx.so也算了进来。 比如, X程序, 本身占用内存为5M, lib.xx.so 占用内存2M,lib.xx.so被N个程序共享依赖。 则RSS显示为,X程序运行,占用内存为7M。 实际上, X程序占用了5M空间。 多余的2m被讨入到RSS中了。 当你在用ps aux显示内存占用情况时, N个共享依赖lib.xx.so的N个程序,都把这2m空间,算在自己的RSS中了, 这样RSS的sum值,就比实际物理内存多了。 当然, linux的内存使用机制很复杂, 不是一句两句能说清楚的。这里只是简单的说明了一下, ps aux中的RSS值, 并不能真实反映物理内存的使用情况。

### 关于Linux系统中VIRT内存占用过大的原因及解决方案 #### 一、VIRT内存的概念 在Linux系统中,`VIRT`代表虚拟内存的总大小,它包括进程实际使用的物理内存(RES)、交换空间中的数据以及映射到磁盘上的文件。因此,即使系统的物理内存并未完全耗尽,也可能观察到较高的`VIRT`值。 #### 二、VIRT内存占用过大的常见原因 1. **Java应用的影响** 如果系统运行了基于JVM的应用程序(如JBoss或Tomcat),这些服务可能会分配大量的虚拟内存来满足其需求[^1]。尽管部分内存可能未被实际使用,但它仍然会显示在`VIRT`统计中。 2. **代码逻辑问题** 应用程序可能存在设计缺陷,例如未能及时释放已申请的资源或存在内存泄漏的情况。这种情况下,虽然应用程序的实际访问量较低,但其虚拟内存消耗却居高不下[^2]。 3. **大页内存支持** 当启用了透明大页(Transparent Huge Pages, THP)功能时,某些工作负载可能导致更高的虚拟内存报告值。这是因为操作系统尝试通过合并连续的小页面为更大的块以提高性能,但这也会增加`VIRT`数值。 4. **共享库加载行为** 对于依赖大量动态链接库的应用来说,在启动阶段就会将所有必要的.so文件映射进地址空间,即便有些函数从未被执行也会计入总的VIRT尺寸里[^3]。 #### 三、解决方法 针对不同类型的场景可以采取相应的措施: 1. **优化Java参数设置** 调整GC策略及相关堆选项能够有效控制由JVM引起的不必要的虚存增长。比如减少初始和最大堆容量(-Xms,-Xmx),启用G1收集器等都是可行的办法之一[^1]。 2. **分析并修复潜在的编程错误** 使用专业的工具链(Valgrind/AddressSanitizer)定位是否存在越界写操作或者其他形式的非法指针引用从而引发隐匿性的缓冲区溢出等问题;另外还需特别关注循环引用导致无法回收对象实例的情形[^2]。 3. **禁用THP特性** 编辑/etc/default/grub 文件添加 kernel cmdline 参数 `transparent_hugepage=never`,之后更新引导记录(grubby --update-kernel /boot/vmlinuz-$(uname -r)) 并重启机器即可生效. 4. **定期清理无用缓存** 执行如下脚本可以帮助临时缓解因为脏数据累积造成的假象式的内存紧张状况: ```bash #!/bin/bash sync && echo 3 > /proc/sys/vm/drop_caches ``` 注意:此方式只是清除了kernel buffer/cache,并不会影响真正的业务处理能力,但对于长期健康状态维护意义不大。 #### 四、总结 通过对以上几个方面的深入理解和实践调整,大多数时候都可以显著降低Linux环境下VIRT指标异常增高的现象发生概率及其带来的负面影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值