云联信息:内存溢出不是加内存就能解决
一、先确认是不是真的内存不足
用free看可用内存,注意系统缓存也占内存,buff/cache高不代表真的不够。看available这一项更准确。
二、看OOM日志找被杀进程
系统日志里会记录被内核杀掉的进程和当时的调用栈。这一步能快速判断是应用本身吃内存,还是被其他进程挤占。
三、应用层要看堆和线程
Java应用看堆内存和GC日志,频繁Full GC说明内存回收不过来;其他语言看是否有内存泄漏。工具不同,思路一致:找到持续增长的那块。
四、连接数和线程数要一起看
大量连接未释放、线程池无上限,都会把内存吃满。表象是内存问题,根因是资源没回收。
五、配置上限防止连锁反应
给应用设内存上限,超限重启而不是拖垮整机。同时限制线程池和连接池大小。一个服务出问题,不应该影响同机其他服务。
六、加内存前先看增长曲线
内存持续线性增长,说明有泄漏,加内存只是延后爆发。内存呈锯齿状波动,属于正常回收,加内存能缓解但不解决根本。
七、调整参数要一次一个
同时改堆大小、GC策略、线程数,出问题无法判断是哪个起作用。每次只改一项,观察一天,再做下一步。
八、压测复现比线上猜好
在测试环境模拟相同流量,观察内存曲线。能复现的问题都好解决,线上靠猜往往越查越乱。
九、留一份现场
出问题时先抓一份内存快照或者线程栈,再重启。重启之后现场就没了,同样的问题下次还会再来一遍。
看内存要先看可用值
free命令里的free列不准,buff/cache会占用大量内存但可回收。看available列才是真实可用内存。误读这一项,很容易做出错误判断。
OOM 之后要保留现场
进程被杀之后,堆栈、GC日志、线程快照都要在重启前抓下来。没有现场,下次还会重复同样的问题。
内存泄漏的典型特征
重启后内存正常,运行几天持续上涨,重启又恢复。这种锯齿状的长周期曲线基本可以判定为泄漏,需要结合堆分析定位。
限制要分层设置
容器层、进程层、线程池层都要设上限。任何一层没设,都可能成为压垮系统的缺口。上限按压测结果定,而不是拍脑袋。
内存问题要结合业务看
同样的内存曲线,在定时任务密集的时段上涨属于正常,在闲时上涨才可疑。把内存曲线和业务流量曲线叠在一张图上,判断会准确得多。
云联信息【资深云服务专家微信:cloud7591】的建议是上线前先压测再扩容,凭经验估容量十次有八次估偏。如果同一台机器上跑了多个服务,还要看是哪个服务在涨,别让一个服务的问题拖垮整台机器。
