# 操作系统内存占用场景分析

一、Windows系统下内存占用分析 (一)检查任务管理器,分析占用内存高的进程 (二)默认参数配置部署后各服务内存占用情况 (三)任务管理器查看进程总内存与已使用内存差距较大,运用RAMMap工具分析 (四)检查是否部署sqlserver数据库,最大服务器内存是否限制 (五)更新S1避免触发操作系统内存泄露 二、Linux系统下内存占用分析 (一)Linux系统下通过free -g观察系统内存整体情况 (二)Linux系统下通过top观察各个进程内存占用情况 (三)Linux操作系统也需要设置虚拟内存(swap分区) (四)默认参数配置部署后各服务内存占用情况 三、致远V5协同服务堆内存分析 (一)协同服务系统监控JVM表格解读 (二)内存溢出宕机,堆内存dump文件分析 (三)Linux系统下协同服务内存增量分析

一、Windows系统下内存占用分析 (一)检查任务管理器,分析占用内存高的进程 Windows系统下通过任务管理器查看各进程使用内存情况 windows 2008:任务管理器—进程—查看—选择列 windows 2008以上版本:任务管理器—详细信息—右建点击列名称—选择列

勾选工作集(内存)、提交大小、命令行

分别以倒序排列工作集内存、提交大小,观察较大的进程,并通过名称和命令行来分辨具体服务。 注意:提交大小(类似linux的VIRT)是包含进程的虚拟内存(swap)占用,不能直接反映进程实际占用的物理内存大小;当系统虚拟内存或swap设置不足时,是以物理内存当做虚拟内存使用,因此会挤压物理内存使用率;因此必须保证虚拟内存分配充足。

(二)默认参数配置部署后各服务内存占用情况 不考虑JVM堆外内存配置,各基础服务内存占用情况: V5协同服务+转换服务+S1+全文检索服务=4G+4G+4G+4G=16G

个别环境数据库服务集中部署,再加上操作系统自身内存消耗;16G物理内存,协同服务极不稳定,必然宕机。

解决以上问题,建议分离部署,无分离部署条件则考虑扩容服务器资源,参考安装部署手册服务器要求:16核CPU,48G物理内存。 ![]

V5协同服务,安装程序自动调整JVM内存为物理内存一半,最小4G OfficeTrans转换服务4G S1致远服务4G 全文检索ES服务2G 全文检索微服务2G (三)任务管理器查看进程总内存与已使用内存差距较大,运用RAMMap工具分析

Windows系统下任务管理器查看到各进程工作集内存或提交大小之和不高,但实际内存使用率很高。可以观察分页缓冲池大小和非分页缓冲池大小。

以上右图:服务器物理内存128G,任务管理器中,查看到页面缓冲池占用99.2G,占总内存的77%,导致系统内存占用过高。

较大的页面缓冲池需要重启操作系统释放。如果一个程序占用的页面缓冲池内存不断增大则可能是内存泄露;

缓冲池产生原因一般为: 1、操作系统内存泄漏 2、操作系统感染病毒木马 3、第三方安全软件导致操作系统内存泄漏(常见为360)

解决方法: 1、重启服务器释放缓冲池内存 2、若增长较快,联系服务器厂商分析或迁移/更新操作系统 3、安全相关导致可以卸载替换其它安全软件重启服务器,全盘扫描

如果页面缓冲池不大,而是进程pid号很大,如达到几十上百万,则可能是windows操作系统bug导致的内存泄漏问题;pid倒序排列,部分环境可以看到不断有新的cmd、find等进程出现,且pid数字越来越大。

其它Windows系统内存泄漏问题,借助rammap工具来进行分析

https://docs.microsoft.com/zh-cn/sysinternals/downloads/rammap

Process Private: 分配给单一Process专用的内存 Mapped File: 用来储放档案内容快取(Cache)的内存空间 Shared Memory: 标注给多个Process共用的内存分页(Page,内存管理单位) Page Table: 用来描述虚拟内存位址的分页表(裡面是一笔一笔的PTE,Page Table Entries) Paged Pool: 允许移至硬盘的核心集区内存(Kernal Pool Memory) Nonpaged Pool: 不允许移至硬盘的核心集区内存 System PTEs: 与I/O空间、核心堆叠、内存描述清单等系统分页相关的PTE Session Private: 登入工作阶段相关的内存 Metafile: 是系统快取的一部份,包含NTFS Metadata(包含MFT及其他NTFS Metadata档案)。在MFT中,每个档案属性记录佔用1K,而一个档案至少有一个属性记录,再加上其他NTFS Metadata档,当档案数众多,这块会很快速成长。 AWE: 启用Address Windowing Extension技术所使用的相关内存空间(较常应用在SQL或其他DB) Driver Locked: 驱动程式锁定的实体内存。多用于I/O的暂时性小量应用,如果有装RAMDisk,也会算在这一区。 Kernel Stack: 核心执行绪推叠,执行绪愈多,用量愈大。 Active: 正在使用中的实体内存分页(Process Working Set或System Working Set) Standby: 留在实体内存但暂不使用的分页,保留供后续能快速重覆利用 Modified: 与Standy类似,但内容被修改过,重覆使用前要先回写到硬盘机 Modified no write: 与Modified类似,但标注为不需回写到硬盘 Transition: 在分类之间转换的分页 Zeroed: 内容已清空可供使用的分页,系统刚开机时明显增加,随著使用一段时间逐步转为Standby Free: 可以使用但残留先前资料的分页,使用前需先转为Zeroed Bad: 标注损坏的内存

分析方法实践: https://xt.seeyon.com/seeyon/bbs.do?method=bbsView&articleId=-5463530445710408075&spaceType=&spaceId=

(四)检查是否部署sqlserver数据库,最大服务器内存是否限制

宕机场景: 服务器Windows操作系统,物理内存16G 未配置Windows操作系统虚拟内存,默认为0MB 集中部署SQLServer数据库,未限制数据库最大服务器内存

数据库消耗大量内存导致协同服务频繁宕机或者无法启动。无法启动服务截图如下。 页面文件太小,无法完成操作。

解决方法: 临时解决,配置Windows操作系统虚拟内存为磁盘可用空间较大分区上系统管理的大小

此电脑,属性,右侧高级系统设置

临时解决,限制SQLServer数据库最大服务器内存为合理的值(此例中物理内存16G,此处配置4096M或者更小)

(五)更新S1避免触发操作系统内存泄露

2022年02月集中收到Windows操作系统内存泄漏引起协同服务宕机

诊断结论: S1触发Windows操作系统缺陷,操作系统内存泄漏引起协同服务宕机。

解决办法: 下载并根据部署说明更新S1最新版本。

https://service.seeyon.com/patchtools/tp.html#/patchList?type=S1&id=24


问题现象: 1、服务器都是Windows操作系统(Windows Server 2008\2012\2016等) 2、服务器重启后几小时到几天之内,操作系统内存使用率不断增加至100%协同服务宕机 3、查看任务管理器,运行进程内存使用量之和远低于系统总内存大小

复现过程: 1、启动RAMMap.1.60\RAMMap.exe工具,选择Process,PID列降序如下图所示,pid数字大小达到10w+且包含大量netstat、find、cmd进程;点击File-Refresh刷新,可以看到pid数字大小持续增加,则存在上述内存泄露问题

2、Windows Server 2016测试服务器验证,脚本循环执行netstat命令(每秒3次),在持续运行20小时候后内存占用增长了7G,增长部分通过rammap查看都是page table、页面缓存池和非页面缓冲池

微软论坛过往案例: https://social.technet.microsoft.com/Forums/msonline/en-US/69879cec-902c-424a-b391-4e9d7aea5385/windows2008r2-sp1?forum=WinServerPreviewZHCN

二、Linux系统下内存占用分析

(一)Linux系统下通过free -g观察系统内存整体情况 Linux系统free很低,实际used内存也不高,大量内存集中在buff/cache部分, avail较高;这个是linux系统特性决定的,将大量内存充当缓存以提高运行效率,当有程序需要使用内存时,buff/cache中的内存会迅速释放,分配给程序,因此无需处理。

(二)Linux系统下通过top观察各个进程内存占用情况 top执行以后,再按M以内存大小降序显示

(三)Linux操作系统也需要设置虚拟内存(swap分区) free -g命令执行,如果看到swap为0,有很高宕机风险。

以下截图swap分区为3G大小,推荐至少16G。

(四)默认参数配置部署后各服务内存占用情况

不考虑JVM堆外内存配置,各基础服务内存占用情况: V5协同服务+转换服务+S1+全文检索服务=4G+4G+4G+4G=16G

个别环境数据库服务集中部署,再加上操作系统自身内存消耗;16G物理内存,协同服务极不稳定,必然宕机。

解决以上问题,建议分离部署,无分离部署条件则考虑扩容服务器资源,参考安装部署手册服务器要求:16核CPU,48G物理内存。

使用命令ps -ef | grep java查询已启动各项服务参数

V5协同服务,安装程序自动调整JVM内存为物理内存一半,最小4G

OfficeTrans转换服务4G

S1致远服务4G

全文检索ES服务2G 全文检索微服务2G

三、致远V5协同服务堆内存分析 (一)协同服务系统监控JVM表格解读 当V5协同服务进程占用内存比较大时,检查jvm参数配置(参考上文建议)是否合理; 其占用的内存包括堆内存(-Xmx:最大堆内存)与堆外内存(Metaspace、CodeCache等),-Xms是初始堆内存,因此V5协同服务java进程占用的最大内存是可以大于-Xmx设置的。

同时需要知道,在操作系统上看,jdk1.8/openjdk1.8,java进程的内存占用是不会被操作系统回收的,只要没有达到最大内存限制,就可能持续增加;

因此如果需要下调-Xmx值,需参考以下数据:

登录系统管理员——系统维护——系统监控,观察堆内存年老代内存使用率 当堆内存年老代峰值使用率没有超过80%,同时当前使用率较低,可以适当下调-Xmx值; 当超过80%,则有内存溢出的风险,应增加-Xmx值或者分析堆内存是否泄露;

如果观察到其当前使用率随着运行时间增加持续增涨不断升高,则可能有内存泄漏,需要导出内存dump分析,或者Linux系统下部署内存火焰图脚本工具,并转交研发处理。

(二)内存溢出宕机,堆内存dump文件分析 内存溢出宕机,通常登录页无法打开,网页无任何响应。典型现象

1、登录页以及各个功能操作频繁卡顿 2、系统监控jvm表格,Old Gen,使用率和峰值使用率超过80% 3、java进程占用内存大小大于等于jvm配置Xmx大小 4、控制台可能输出java.lang.OutOfMemoryError: Java heap space 5、jstat -gcutil命令可见堆内存年老代耗尽

控制台或者OA日志输出 java.lang.OutOfMemoryError: Java heap space

有时候java会自动dump,如以上截图,产生了一个java_pid20487.hprof文件位于 ApacheJetspeed/bin目录下;

若未自动完成,可以手工导出heapdump文件,jdk/bin目录下执行命令:

jmap -dump:format=b,file=文件名.bin java进程pid数字

内存溢出问题通常必须要分析heapdump文件。

分析工具常用 MemoryAnalyzer,俗称MAT,下载地址: https://www.eclipse.org/mat/downloads.php https://www.eclipse.org/mat/previousReleases.php 下载后配置其中MemoryAnalyzer.ini文件,如图:

上图中, javaw.exe文件路径根据实际情况修改,jdk1.8版本。 heapdump文件有多大,-Xmx8g 这个配置就改成多大,并且分析问题差不多需要这么大的内存。

打开heapdump文件后选择 Leak Suspects Report,Finish。

分析报告交由研发解读。

(三)Linux系统下协同服务内存增量分析 某一段时间V5协同服务java进程内存占用上涨,系统并未宕机但出现卡顿,分析此类问题需要借助async-profiler。

async-profiler 是一款开源的 Java 性能分析工具,原理是基于 HotSpot 的 API,以微乎其微的性能开销收集程序运行中的堆栈信息、内存分配等信息进行分析。

问题案例:系统卡顿严重,system系统监控可见Old Gen使用率频繁涨跌;

jstat命令观察内存回收同样看到年老代使用率频繁涨跌;

根据以下说明部署内存火焰图脚本工具至任意目录,nohup启动脚本工具开始抓取内存火焰图dump日志。

创建人:zhengkejie
修改人:het