内存压力过高怎么处理

本文详细介绍了Linux系统中查看内存状态的命令,包括top、free、vmstat、/proc/meminfo和sar,并解析了缓冲、缓存的作用。针对进程占用内存过高、缓存占用导致内存不足以及内存泄漏和内存溢出的问题,提供了诊断和解决方法,包括使用top命令监控、手动释放缓存以及调整系统参数。同时,探讨了内存泄漏的分类和内存溢出的原因,提出了相应的解决策略。
摘要由CSDN通过智能技术生成

内存压力过高如何处理

一、查看内存状态的命令

1、top

image-20220530233055408

2、free

常用选项

选项含义
-b以字节为单位显示
-k以kb为单位显示(free默认)
-m以mb为单位显示
-g以GB为单位显示
-h友好显示
-s 间隔秒数持续观察内存使用情况
-t显示内存总和列

image-20220530234133787

缓冲(buffer): 当我们操作需要从磁盘中读取文件时,内核先查看文件是否在缓存中,如果在的话,直接读取,就不需要再从磁盘中读取。如果不在,内核就会调度块I/O去磁盘中读取,然后内核将读来的数据放在缓存中。

缓存(cache): 当我们需要写入文件到磁盘中,不会直接写入到磁盘中,会先写入到缓存中,用来减少对磁盘的I/O操作。

free和available: 两个都是空闲内存,不过free表示真正没有被使用的物理内存数量,而available则表示从应用程序的角度看到的可用内存数量。

Linux内核为了提升对磁盘的操作性能,会消耗一部分内存去缓存磁盘中的数据,就是buffer和cache,所以对于内核来说,这两个都是属于已经被使用的内存,当应用程序需要内存时,没有足够的free内存,内核就会从缓存中国后手内存来满足应用程序。

3、vmstat

动态查看系统资源使用情况。以及查看当前系统中到底哪个环节最占用系统资源。

vmstat命令,是 Virtual Meomory Statistics(虚拟内存统计)的缩写。

可以用来监控CPU使用、进程状态、内存使用、虚拟内存使用、硬盘输入、输出状态等信息。

格式:

vmstat    [-a]   [刷新延时   刷新次数]

vmstat    [选项]

常用选项

选项含义
-fs-f:显示从启动到目前为止,系统复制的程序数,此信息从/proc/stat中的processes字段中获取的。
-s:将从启动到目前为止,由一些事件导致的内存变化情况列表说明
-S 单位令输出 的数据显示单位,例如K/M
-d列出硬盘有关读写总量的统计表
-p 分区设备文件名查看硬盘分区的读写情况

image-20220531091133175

以上解释:

进程信息(proc)

  • r:等待运行的进程数,越大系统越忙
  • b:不可被唤醒的进程数量,越大系统越忙

内存信息(memory)

  • swpd:虚拟内存的使用情况,单位KB。以下都是。
  • free:空闲的内存容量
  • buff:缓冲的内存容量
  • cache:缓存的内存总量

交换分区信息(swap)

  • -si:从磁盘中交换到内存中数据的数量。
  • -so:从内存中交换到磁盘中数据的数量。

注:这两个数越大,标明数据需要经常在磁盘和内存之间进行交换,系统性能差。

磁盘读/写字段(io)

  • bi:从块设备中读入的数据的总量,单位是块
  • bo:写到块设备的数据的总量,单位是块

注:这两个数越大,代表系统I/O越繁忙

系统信息字段(system)

  • in:每秒被终端的进程次数
  • cs:每秒进行的事件切换次数

注:这两个数越大,代表系统与接口设备的通信越繁忙

CPU信息字段(CPU)

  • us:非内核进行消耗CPU运算时间
  • sy:内核进行消耗CPU运算时间的百分比
  • id:空闲CPU的百分比
  • wa:等待I/O所消耗的CPU百分比
  • st:被虚拟机所盗用的CPU百分比

4、/proc/meminfo

可以读取/proc/meminfo文件用来查看内存的状态,/proc目录下都是虚拟文件,包含内核及操作系统相关的动态信息。

image-20220605135006228

5、sar

sar命令也可以用来监控Linux的内存使用状态,通过“sar -r”组合可以查看系统内存和交换空间的使用率。

输出的内容统计占比,相对free来说,更加直观一些。

常用选项

sar命令选项功能
-A显示系统所有资源设备(cpu,内存,磁盘)的运行状况
-u显示cpu
-P显示当前系统中指定的CPU的使用情况
-d显示硬盘
-r显示内存
-q显示运行列表中的进程数,进程大小,系统平均负载
-R显示进程的活动情况
-y显示终端设备活动情况
-w显示系统交换活动的状态

image-20220605140415540

二、故障分析及解决

1、进程占用太多的内存

1.1 模拟进程占用资源

前面介绍了buff和cache表示了缓冲和缓存,每当对磁盘进行读写操作时,都会先对缓存进行操作,因为缓存是需要消耗内存的,虽然缓存中的内存会自动释放,但是只有当物理空闲内存不够的时候,缓存中才会释放一些内存出来,释放的也仅仅是够用,不会全部释放。

下面进行模拟内存占用。

下载网址:Index of /software/memtester/old-versions (pyropus.ca.)

进行下载内存压力测试工具,一个压缩包,把它放在linux系统中进行解压

image-20220531105742301

进入解压后的文件,

image-20220531105809988

安装gcc运行环境

image-20220531105840439

然后进行编译

image-20220531105906064

编译之后在当前目录下有运行的程序

image-20220531110059151

测试前使用free -h 查看内存使用情况:空闲内存还有561M,buff/cache占用869M

image-20220531110925727

然后进行测试500内存

image-20220531111107286

再次查看内存情况

image-20220531111218852

1.2 解决办法

使用top命令查看哪个进程占用太多,按M,进行内存排序,发现我们内存压力测试的占用过高,

image-20220605104243046

如果在生存环境中,这个是一个莫名的程序,可以将它杀掉,从而进行释放内存。

按k键会top会自动找到占用内存最大的进行号,按Enter键,可以将它杀掉。

image-20220605104410968

发出一个sigterm信号将其干掉。

image-20220605104946707

再查看内存状态,恢复到之前的容量

image-20220605104913008

2、缓存占用过高导致内存不足

2.1 查看缓存占用

image-20220605105226278

缓存占用的原因

根据内存的情况,看到缓存中也占用的较大,前面介绍了buff和cache表示了缓冲和缓存,每当对磁盘进行读写操作时,都会先对缓存进行操作,因为缓存是需要消耗内存的,虽然缓存中的内存会自动释放,但是只有当物理空闲内存不够的时候,缓存中才会释放一些内存出来,释放的也仅仅是够用,不会全部释放。

2.2 解决办法

所以需要我们进行手动释放内存

手动释放cache中的内存

在释放前,可以使用sync命令,将内存中的数据强制写入到磁盘中,避免数据丢失

/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel(操作系统内核)实体间进行通信的一种手段.也就是说可以通过修改。
/proc中的文件,来对当前kernel的行为做出调整.那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。要达到释 放缓存的目的。
我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就是不释放缓存。

再用以下命令将手动释放缓存中占用的资源

image-20220531112603144

参数解释

1:表示释放页缓存

2:释放dentries和inodes

3:释放所有缓存

在查看一下现在内存情况

可以看到,缓存中的内存大小变的较小,因为它将不经常使用的程序的缓存释放。

image-20220531112716657

3、内存泄漏和内存溢出方向

什么是内存泄漏?

是指程序在申请内存后,无法释放已申请的内存空间,多个程序申请内存后,会导致内存空间不足。

什么是内存溢出?

程序申请内存时,没有足够的空间供其使用,出现内存溢出。

内存泄漏最终会导致内存溢出

3.1 内存泄漏可以分成4类

①常发性内存泄漏: 发生内存泄漏的代码会被多次执行到,每次执行的时候都会导致一块内存泄漏。

②偶发性内存泄漏: 发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生,长发性和偶发性是相对的,对于特定的环境,偶发性的也许就变成了长发性,所以测试环境和测试方法对检测内存泄漏至关重要。

③一次性内存泄漏: 发生内存泄漏的代码只会被执行一次,由于算法上的缺陷,导致总会有一块仅且有一块内存发生泄漏。

④隐式内存泄漏: 程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存,严格的说这里并没有发生内存泄漏,因为最终程序释放了所申请的内存,但是对于一个服务器程序,需要运行几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。

3.2 内存溢出的原因

①内存中加载的数据过于庞大,如一次从数据库读取过多的数据,内存供给不足,导致内存溢出。

②集合类中有对对象的引用,使用完后未清空,使得JVM(运行java代码的容器,相当于一台java虚拟机),不能回收。

③代码中存在死循环或循环产生过多重复的对象实体。

④使用第三方软件的bug

⑤启动参数内存设定的过小。

3.3 解决内存溢出的方法

第一步:修改JVM启动参数,增加内存。

第二步:检查错误日志。

第三步:分析代码

①检查对数据库查询中,是否有一次获得全部数据的查询,一般来说,如果一次取十万条记录到内存中,就可能引起内存溢出,这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出现问题,上线后,数据库中的数据多了。一次查询就有可能引起内存溢出,因此对于数据库查询尽量采用分页的方式查询。

②检查代码中是否有大循环重复产生新对象实体。

③检查代码中是否有死循环或递归调用。

三、总结

查看内存状态的命令(top、free、vmstat,sar,/proc/meminfo)

导致内存不足的三个原因(进行占用太高、缓存占用过高没有进行释放、内存泄漏和内存溢出导致内存不足)

果一次取十万条记录到内存中,就可能引起内存溢出,这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出现问题,上线后,数据库中的数据多了。一次查询就有可能引起内存溢出,因此对于数据库查询尽量采用分页的方式查询。

②检查代码中是否有大循环重复产生新对象实体。

③检查代码中是否有死循环或递归调用。

三、总结

查看内存状态的命令(top、free、vmstat,sar,/proc/meminfo)

导致内存不足的三个原因(进行占用太高、缓存占用过高没有进行释放、内存泄漏和内存溢出导致内存不足)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值