bug经历: 物理内存耗尽,但是不知道是哪个进程干的

最近我发现一个很奇怪的事情,tensorflow的windows版有一个很奇怪的内存泄露的bug。我的电脑有16GB内存。但是tensorflow一旦跑起来,机器很快就会内存不足,然后page file频繁的换入换出。但是tensorflow这个进程本身呢,并没有内存泄露。它的堆并没有增长。我用windbg仔细检查过它的所有内存,堆的,栈的,各种类型的,都没有增长。嗯,电脑突然没了10几GB的物理内存,但是tensorflow只占了几百M。我把这个电脑里所有进程的所有内存使用量加起来,也远远不够10GB。我可以肯定是tensorflow干的。因为我一旦把tensorflow的进程杀死,丢失的内存立马就回来了。一旦重新启动tensorflow,内存又逐渐的没了。

最终,我发现,是我的一个美国同事,checkin了一个很糟糕的修改。他给tensorflow的windows file system的实现引入了两个很严重的bug。
他原始的pull request是:https://github.com/tensorflow/tensorflow/pull/5020
第一个被发现的bug是:https://github.com/tensorflow/tensorflow/pull/6805
第二个就是我刚才说的,内存泄露。

sysinternals里有两个工具可以查看内存去哪了。一个是vmmap。是查看单个进程的。另一个是RAMMAP,可以查看物理内存具体被map到哪去了。最终我发现,是以memory mapped file的方式消耗掉了。而那个file就是tensorflow运行时正在读的那个file。

揭秘的时刻来了。原来是它打开文件的时候加了FILE_FLAG_RANDOM_ACCESS参数。然后windows内核在看到这个参数后,就会把所有已读入的内容,一直lock在内存里。参见https://support.microsoft.com/en-us/help/2549369 。 不加这个参数,文件系统也会做cache,但是这部分内存的类型是Standby。加了这个参数,这部分内存就变成了Active状态。

最后,我把这个报告了给tensorflow的github仓库,看看他们准备怎么办。https://github.com/tensorflow/tensorflow/pull/8522

BTW,我觉得这个特性可以用来攻击yarn等云服务啊。yarn的container memory constrain应该是不会把这种内存记进去的吧?

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥