我遇到了一个问题,我的ASP.NET 4 MVC 2 + WCF应用程序在Windows 2008 64位应用程序中进行负载测试时会使用大量内存,几分钟后就会使用掉几乎所有可用内存(8 GB)(我们有几个工作进程在运行)。
使用ANTS Memory Profiler进行分析后,它显示了一些有趣的结果:
1. .NET托管内存从15 MB增加到40 MB,但这归因于我们在程序中使用的缓存机制。然而,.NET本身分配了近180 MB的空闲空间,这是意外的。
2. 非托管内存大小显著增加,直到负载测试运行约3分钟后达到120 MB(尽管我们的应用程序没有明确使用任何P/Invoke或COM对象。但是我们确实使用了一些COM+对象,在finally块中使用后被释放)。
3. 内存变得分散。
以上两点导致整个应用程序在负载测试运行几分钟后使用约350 MB,但如果我们不停止测试,它将继续增长。
基于以上第一点,我测试了一些应用程序,以测试问题是否由我们的应用程序或WCF引起。当逻辑存储在EXE程序中时,应用程序仅使用24 MB私有字节中的200 KB(开始时额外使用了120 KB未使用的内存),并在完成后释放(这是可以接受的);但当逻辑存储在WCF中时,应用程序使用了66 MB托管内存(从开始的61 MB增加到64 MB的空闲/未使用托管内存)。因此,似乎是WCF/ASP.NET导致内存大量增加。
以下是需要回答的问题:
1. 为什么.NET在堆中分配了这么多的空闲空间?虽然理解空闲空间可能是在内存快照过程中进行GC的某些Gen 0/Gen 1/Gen 2,但我不认为应用程序真正使用了那么多内存。
2. WCF的行为是否正常?如果是,有没有办法改变它的行为,使其使用更少的内存?
3. 如何找到非托管内存泄漏,特别是我没有明确使用非托管代码的情况下?
使用ANTS Memory Profiler进行分析后,它显示了一些有趣的结果:
1. .NET托管内存从15 MB增加到40 MB,但这归因于我们在程序中使用的缓存机制。然而,.NET本身分配了近180 MB的空闲空间,这是意外的。
2. 非托管内存大小显著增加,直到负载测试运行约3分钟后达到120 MB(尽管我们的应用程序没有明确使用任何P/Invoke或COM对象。但是我们确实使用了一些COM+对象,在finally块中使用后被释放)。
3. 内存变得分散。
以上两点导致整个应用程序在负载测试运行几分钟后使用约350 MB,但如果我们不停止测试,它将继续增长。
基于以上第一点,我测试了一些应用程序,以测试问题是否由我们的应用程序或WCF引起。当逻辑存储在EXE程序中时,应用程序仅使用24 MB私有字节中的200 KB(开始时额外使用了120 KB未使用的内存),并在完成后释放(这是可以接受的);但当逻辑存储在WCF中时,应用程序使用了66 MB托管内存(从开始的61 MB增加到64 MB的空闲/未使用托管内存)。因此,似乎是WCF/ASP.NET导致内存大量增加。
以下是需要回答的问题:
1. 为什么.NET在堆中分配了这么多的空闲空间?虽然理解空闲空间可能是在内存快照过程中进行GC的某些Gen 0/Gen 1/Gen 2,但我不认为应用程序真正使用了那么多内存。
2. WCF的行为是否正常?如果是,有没有办法改变它的行为,使其使用更少的内存?
3. 如何找到非托管内存泄漏,特别是我没有明确使用非托管代码的情况下?