之前, 我曾经写过一篇文章Task Manager跟Performance Monitor的区别(Working set和Private bytes), 对Windows内存的解释并不是很清楚.
最近从头到尾听了一遍Mark Russinovich的Windows内存的讲座, 于是把笔记记录在这里.
内存基础
===========================
内存地址分为三部分:
- Private – 举例: 进程堆
- Reserved 或 Committed
- Shareable – 举例: EXE, DLL, Shared Memory, Other memory mapped files
- Reserved 或 Committed
- Free
在Performance Monitor中, 有如下的counters.
- Private Bytes – 为Committed private memory
- Virtual Bytes – 为total of Shareable + Private (including reserved)
对Shareable或者Reserved, 或者Free的内存是没有单独的counter的.
Committed和Reserved的区别是什么呢?
============================
比方说, 我们需要八个人一起吃饭, 但是这个八个人不能同时到达饭店. 所以, 我们需要订一个八人的桌子. 订的八人桌就是reserved, 但是先到并坐下的人就是committed的了.
进程中的Stack就是这种概念的典型应用, 调用栈必须连续, 但是却不是一次性占满的, 随着程序调用的深入, Reserve了的栈的空间会一点点的被commit.
Take Manager
============================
Task Manager中可以看到如下的一些项目.
其中, 默认的列Memory –Private Working Set跟virtual memory毫无关系, 由于下面也说到的working set trimming, 这个column也不能反映该进程对整个系统的内存造成的影响, 实际上没啥用.
其中, Memory-Commit Size跟Private Byte是相等的. 在Vista之前, 这个column叫做VM Size. Vista及之后它叫做Commit Size.
绝大多数的内存问题都已由于进程泄露了Private Committed memory引起的, 比如说Heap, GC heap.
但private byte这个counter并不会透露全部的内存信息, 比如说对于内存碎片, 或仅由本进程加载的DLL所申请的共享内存.
想查看更多内存信息, 可以通过Sysinternal的一个叫做VMMap的工具.
图中的Image, Mapped File, Shareable是可以与其他进程共享的. 下面的都是private的.
什么是Working Set?
=====================
进程启动的时候总是从一个空的working set开始的.
之后该进程在试图访问内存页面的时候, 会发生page fault, 因为这个page不在working set里.
在内存充足的时候, process working set代表着所有该进程引用过的内存(还没有释放的).
在内存不足的时候, working set会被压缩.
当Memory manager觉得该进程足够大了, 那么这个进程的某些内存页面会被抛弃, 为新页面腾出空间. 抛弃页面的算法类似”队列先进先出”加”最后访问的最后淘汰”.
Working Set包含两类page
- Shareable
- Private
Performance Counter有如下三个counter来显示这些信息.
- Working Set Shareable
- Working Set Private
- Working Set Size (上面二者之和)
一些要点, Working Set在内存不足时是会被trim掉的, 所以这有时并不能反应该进程的内存饥渴程度.
检查内存问题的可靠的数据来源
===================
Process Explorer中的Virtual Size, Private Bytes, Working Set.
举例, Sysinternal上有个叫做TestLimit的tool, 专门用来测试内存的.
测试命令如下:
· TestLimit -r 1024 -c 1
- o Reserve 1G内存
· TestLimit -m 1024 –c 1
- o Commit 1G 内存, 但不访问这些内存.
· TestLimit –d 1024 –c 1
- o Commit 1G内存, 而且访问这些内存.
Task manager中可以看到如下的信息. 可以看出并不能良好区分这三者.
在Process Explorer中可以看到下面的信息.
资料来源
==================
Mysteries of Windows Memory Management Revealed with Mark Russinovich, Part 2
http://channel9.msdn.com/Events/TechEd/Europe/2010/WCL402
Mysteries of Windows Memory Management Revealed with Mark Russinovich, Part 1