这并不是说它很重要,而是因为它是我的一个大麻烦,我想区分真正的内存泄漏和高内存使用率。
内存泄漏是指您使用了一些内存并且丢失了指向分配的指针,因此您无法再取消分配该内存。如果你仍然有一个指向它的指针,你的内存使用率很高,这可能与进程发生的情况一样糟糕,但仍然不同。为了简单起见,我将从现在开始对这两个问题使用术语内存泄漏…
我喜欢考虑解决性能和内存泄漏问题,比如剥洋葱皮。从最明显的一个层开始,一次去掉一个层,然后定义一个限制,确定问题已解决。
有两种类型的内存泄漏,一种是逐渐的内存泄漏(内存以大致相同的速率持续增长)和突然的内存跳跃。您可以用大致相同的方式对它们进行故障排除,但在后一种情况下,您还可以尝试确定在跳转时是否发生了异常情况,例如服务器上的极端负载等。
进程的内存空间包含一些不同类型的“对象”,如线程、管理的对象堆、托管加载程序堆、本机堆、dll和虚拟分配,因此,一个好的开始是运行带有以下计数器的性能监视器日志。
- Process/Virtual Bytes
- Process/Private Bytes
- .net CLR Memory/# Bytes in all Heaps
- .net CLR Memory/% Time in GC
- .net CLR Memory/Large Object Heap size
- .net CLR Loading/Bytes in Loader Heap
- .net CLR Loading/Current Assemblies
主要要寻找的是私有字节的增长率是否与虚拟字节的增长率大致相同,以及所有堆中的字节是否都遵循相同的曲线。
如果私有字节持续增加,但是所有堆中的字节没有增加,那么很可能会看到本机内存泄漏(即,在COM组件或类似组件中泄漏),但如果所有堆中的字节以与私有字节相同的速率增加,则托管代码中可能会出现泄漏。
同样,如果您看到虚拟字节稳步增加,但是您的私有字节保持相当稳定,那么您的应用程序可能存在一个问题,即它保留了大量未使用的虚拟内存。
一旦进程启动并且加载了所有应用程序域,加载程序堆和当前程序集中的字节应该保持相当恒定。如果此值持续增加,则很可能存在总成泄漏。
所以现在你大概知道你在哪里泄露了,下一步就是找出原因