If you think that you are experiencing a memory leak, be aware that memory leaks may not be what they appear to be. You may discover that a memory leak is not a true memory leak, but is a performance enhancement. For example, the Microsoft Jet database engine can consume large amounts of memory (up to 128 MB on a 256-MB computer) because it retrieves data and writes caches. The cache permits the Jet engine to get fast read-ahead and write-ahead buffering.
To determine whether or not a process is experiencing memory leaks, use Windows Performance Monitor (Perfmon.exe) and monitor Private Bytes under the Process category for your application. Private bytes is the total memory that the process has allocated, but is not sharing with other processes. Note that this is different from Virtual Bytes, which is also interesting to monitor. Virtual Bytes is the current size in bytes of the virtual address space that the process uses. An application can leak virtual memory, but may not see a difference in the private bytes that are allocated. If you do not see memory increase when you monitor private bytes, but you suspect that you are still running out of memory, monitor virtual bytes to see if you are using up virtual memory. For additional information about detecting memory leaks and the overview of Windows Performance Monitor (Perfmon.exe), visit the following Microsoft Web site:
http://msdn.microsoft.com/en-us/library/ms404355.aspx (http://msdn.microsoft.com/en-us/library/ms404355.aspx)
To make sure that your application is leaking memory, put the suspect code in a loop with many iterations, and then monitor private and virtual bytes for any increases of memory. Watch to make sure that the number of private bytes and virtual bytes does not eventually stay the same and the number stops increasing. If there is a point at which the memory stops increasing, (for example, it does not continue to climb indefinitely) you do not see a memory leak but more likely, you see a cache that is growing to its maximum size.
To determine if this is a memory leak or fragmentation, start with perfmon.
Review the perfmon log taken during the problem situation.
Look at the process counter for the problem process, and compare the private bytes to virtual bytes.
If private bytes continue to grow without leveling off, then you probably have a private bytes leak. Troubleshoot this as an NT heap leak.
If private bytes level off while while virtual bytes continue to grow then you probably have a virtual memory leak or fragmentation.
NOTE: Virtual memory leaks where the caller is commiting memory will also cause private bytes to grow. In most cases when private bytes grows, it is an NT heap leak, but there is the possibility that it is a virtual memory leak. Start by troubleshooting it as an NT heap leak, and then as a virtual memory leak if needed.
To distinguish between a virtual memory leak and fragmentation:
Compare the memory->committed bytes counter to the process->virtual bytes counter
If the committed bytes counter follows the virtual bytes counter, then you probably have a virtual bytes leak. Troubleshoot this as a virtual memory leak.
If the virtual bytes grow at a faster rate than committed bytes, then you will need to run heapstat to verify this is virtual memory fragmentation.
Caching
Caching situations will usually show up as leaks in leakdiag because they are allocations that have not been freed. In some situations, it is possible to prevent false positives by disabling caching. Otherwise, it would require a code review to identify the allocations are actually being cached for later reuse. If the leaks are showing up in specific allocators, then tracking only that allocator will prevent caching from appearing to be a leak since LeakDiag will tracke the originating allocation call instead of the underlying heap or virtual alloc calls which might be cached by the component. The COM allocator is one example of an allocator that can be used to prevent false leaks due to caching.
在检测是否是一个memory leak时,可以遵照下面的步骤来调查:
1. 使用Performance Monitor对程序进行monitor,其中关键包括Private Bytes,committed bytes 和Virtual Bytes。如果内存增长到某个数值后就不再增加,就应该是因为缓存的原因造成的内存占用偏高;
2. 观察Private Bytes和Virtual Bytes。如果Private Bytes持续增加而没有一个趋平的过程,那么这个程序可能存在Private Bytes leak,可以使用NT heap leak的方法来寻找问题;
3. 如果Private Bytes趋平了,但是Virtual Byte持续增长,这个程序可能存在Virtual memory leak或者碎片
4. 区分Virtual leak和碎片:比较committed bytes 与Virtual Bytes, 如果committed bytes与Virtual bytes相近,程序可能存在Virtual bytes leak;
5. 如果Virtual bytes比committed bytes有更加快速的增长速度,你需要使用heapstat来验证是否这是一个虚拟内存碎片问题了。