记一次 win10 下的内存泄漏分析

前言


在上回 SVN 项目迁移到 Git 的过程中遇到了内存泄漏的问题,本文就这个问题做一次分析和记录。

第一回合


之前对迁移过程做了大量测试,觉得都没问题了,就把项目带回家准备利用周末的时间来迁移,下周其他同事就可以正常提交代码而不用耽误太多时间了。

当然,回家后不会立即开始迁移,先做点正事。迁移的时候电脑应该专心点,免得出现什么未知问题,所以睡觉前开始挂机,醒来估计差不多就好了。嗯,想法很美好。

第二天起来,准备收割胜利的果实,结果发现电脑死机了( 鼠标虽然还能动,但是点啥都没反应,键盘也毫无响应 ),无奈之下只好按电源强制关机了。

第二回合


想起来挂机的时候同时开了两个任务( git subtreegit filter-branch ),会不会是这两个任务冲突了?那就一个一个执行吧,重新开始挂机,出门去。

晚上回来之后,电脑不出意外又死机了。

第三回合


前两次死机的时候我都不在现场,如果我盯着它,干活应该能认真点?强制关机,再次开启任务,打开任务管理器,我倒要看看是什么原因导致的。

开启任务后 CPU 开始飙升,查看进程发现竟然不是 Git 而是 电脑管家的实时防护服务 ,喧宾夺主了吧。想关掉这个服务,试了各种方法都关不掉,最后干脆直接卸载。

卸载完 电脑管家 重新开始任务,结果 CPU 还是飙升,这回是 win10 自带的 Windows Defender ,同理禁用掉。( 后来发现,这两个软件应该是对 Git 产生的大量文件进行扫描,虽然会占用一些 CPU ,但是并没有太大影响,所以不必禁用 )

重新开始后 CPU 就正常了,接下来就是慢慢等待了。半小时,一小时... 一切还算正常,不过内存占用有点上升。按照任务已完成的进度和增长的内存,粗粗算了一下,发现内存根本坚持不到任务结束的那一刻。果然,几个小时之后,内存就满了,磁盘利用率开始飙升,然而任务还有一大半没完成,而且速度越来越慢,不过电脑还能正常使用。继续等待,一个小时后,不出意外,终于死机了。

问题分析


通过上面的试验可以确认,死机的原因是 内存泄漏 了,但是什么原因导致的 内存泄漏 还无法得知。

下面给出本次迁移使用的机器配置

机器 系统 配置 测试结果
公司的闲置笔记本( A ) win10 1703 i5 8G 正常执行迁移任务,不存在内存泄漏
公司的工作笔记本( B ) win10 1803 i5 8G 内存泄漏
家里的笔记本( C ) win10 1709 i5 8G 内存泄漏

既然有一台电脑是正常的,那就可以排除操作系统的问题了,对比下闲置电脑和我日常使用的电脑有哪些差异( 系统配置,安装的第三方软件等等 )。

  1. 首先注意到电脑 A 的虚拟内存配置和其他两台电脑不太一样,那就调成一样或者关掉虚拟内存试试。结果内存还是会泄漏,不过内存用满了之后任务就因为内存不足自动结束了,也就不会死机了。到这一步可得知死机的原因是 物理内存耗尽后,大量使用磁盘虚拟出来的内存 ,但是还没从根源上找到内存泄漏的原因。

  2. 对比任务管理器中的运行的服务,一个个关掉后测试,有点费劲费时( 这真是个笨方法,后来想到重启进入 安全模式 测一遍就好了 )。忽然注意到,前面提到的 电脑管家的实时防护服务Windows Defender 会占用较多的 CPU ,那么和它们类似的 扫描类/底层拦截类 的软件也很有嫌疑。这回把目标瞄准 ADSafe 这个广告拦截软件,禁用服务,再次开启迁移任务。等待了一个小时,内存竟然没有增长,看来 真凶 就是它了。

问题复现


先上截图,看下开启 ADSafe 时的资源使用情况

开机后刚开始执行任务

任务运行半小时后

对比前面两张图看下半小时的数据差异:

  1. 资源管理器中 使用中 增长了 2.1G已提交 增长了 2.9G
  2. 资源监视器中 可用 的内存几乎都转为 正在使用
  3. RAMMap进程私有 增长了 100M映射文件 增长了 1G页表 增长了 1.2G

可以发现进程并没有泄露内存, 映射文件 占用的内存不用太在意,唯一异常的地方在于 页表 这一项。

再上一张 RAMMap 中进程标签页下的截图:

RAMMap 中进程标签页

可以看到大量的进程,其中 PID 由最初的 1W+ 增长到了 18W+ ,而且这些进程大部分在任务管理器是不存在的( 即进程已结束 )。粗粗统计了下,大约有 46000 个进程( sh.exe/git.exe/cat.exe ),每个占用 28K ,合计大约有 1.22G ,正好和上面的 页表 内存增长量相吻合,所以应该是这部分内存无法回收利用导致的内存泄漏( 这估计是系统的 bug ,进程结束应该释放页表占用的内存才对 )。 类似情况

关掉 ADSafe 后再次试验: sh.exe/git.exe/cat.exe 进程数虽然也增加了几十个,但是和前面的 4W+ 比起来完全不是一个数量级。

结论


通过上面的测试,可以定位到内存泄漏的根源: ADSafeGit 有所冲突,导致 Git 不断创建新的进程。至于是什么冲突那就无法得知了,和 ADSafe 说拜拜就好了。

拓展知识


文中用到的内存分析工具

关于任务管理器中的内存指标

类别 说明
使用中 进程使用的内存大小,内存使用率就是用这个值计算的,实际上这个值并没有太大意义。
已提交 ( 已用 ) 所有程序真正占用的内存,当这个值接近或者超过物理内存大小的时候,电脑基本已经开始变卡了,因为这时候已经开始使用磁盘所虚拟出来的内存,想想内存和磁盘的读写速度就知道了。
已提交 ( 总 ) 也就是 虚拟内存 ,等于 物理内存 + 系统盘下 pagefile.sys 文件的大小

关于 使用中已提交 的区别,我的理解是:一个进程向操作系统申请了 1G 的内存,那么这些内存就都归这个进程使用,虽然它现在只使用了 200M ,但剩下 800M+ 应该为这个进程保留,而不能拿去给别的进程使用,这个例子中 已提交 就是 1G使用中200M ,两者之差可以反映出程序的内存利用率。

是否应该禁用虚拟内存( pagefile.sys )

个人不建议禁用。比如我平时工作时,开一个 IDEA 再把工作项目都启动,基本上 8G 的内存都用完了,这时如果我再开个 Chrome 就要用到 虚拟内存 了,内存再挤一点用一点。但是如果我禁用了 虚拟内存 ,就会提示 内存不足 导致程序崩溃,或者需要关闭 其他使用中的程序 腾出内存才能打开新的程序。 虚拟内存 的意义在于: 物理内存 不足的时候使用磁盘来代替内存,虽然会卡一点,但是能满足使用所需( 就是要开这么多程序 )。同样的, 内存不足 这个问题的根本解决办法应该是 加内存并且少开程序 而不是一味的加大 虚拟内存

关于 RAMMap 中的指标

按照我的经验, 剩余可用内存 基本上等于 映射文件( 备用 ) + 未使用( 归零 + 可用 ) 。如果开启了 Superfetch 服务,系统会把一些常用的文件读取到内存( 映射文件 )中,这样程序中用到这些文件的时候就能更快的读取,这部分内存在 内存不足 的时候是可以拿来给其他进程使用。

关于页表

对于页表我也不了解,页表应该就是一个目录结构,保存 内存地址映射关系 ,通过它程序能把内存的 逻辑地址 转为 实际的物理地址


转载请注明出处: //www.greatytc.com/p/7510e57aeaff

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • 1.内存的页面置换算法 (1)最佳置换算法(OPT)(理想置换算法):从主存中移出永远不再需要的页面;如无这样的...
    杰伦哎呦哎呦阅读 3,249评论 1 9
  • 1. 基础知识 1.1、 基本概念、 功能 冯诺伊曼体系结构1、计算机处理的数据和指令一律用二进制数表示2、顺序执...
    yunpiao阅读 5,295评论 1 22
  • 操作系统对内存的管理 没有内存抽象的年代 在早些的操作系统中,并没有引入内存抽象的概念。程序直接访问和操作的都是物...
    Mr槑阅读 16,695评论 3 24
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,097评论 1 32
  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,154评论 0 9