首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Microsoft.Web.Administration内存泄漏

Microsoft.Web.Administration内存泄漏
EN

Stack Overflow用户
提问于 2012-07-17 02:00:35
回答 3查看 1.3K关注 0票数 5

拥有一个windows服务,其中包括监视IIS应用程序池。如果任何池具有已配置的应用程序且未运行,则会启动它(池)。这在一段时间内一直运行良好。最近发现该服务正在泄漏内存。查看内存转储,罪魁祸首是用于检查应用程序池的Microsoft.Web.Administration。唯一可以处理的对象是ServerManager,我把它放在using块中。我已经找到了关于这次泄漏的其他报告,但还没有解决方案。(请参阅http://msdn.microsoft.com/en-us/library/microsoft.web.administration.servermanager(v=vs.90).aspx#CommunityContent中的用户注释

当转储Microsoft.Web.Administration.ServerManager的所有根(在此转储中为481)时,我只看到其中一个根。假设这是当前迭代。

不确定为什么不能收集这些Web.Administration对象,即使它们似乎不是根对象(?)。你有什么办法堵住这个漏洞吗?

我将代码移到了一个控制台应用程序中,并在那里重现了泄漏。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Web.Administration;

namespace Web.Administration.LeakExample
{
    public static class ServerManagerExtensions
    {
        /// <summary>
        /// Returns the application counts for application pools under the specified ServerManager.
        /// Application pools without applications will not be returned.
        /// </summary>
        /// <param name="manager"></param>
        /// <returns></returns>
        public static Dictionary<string, uint> GetPoolApplicationCounts(this ServerManager manager)
        {
            if (manager == null)
            {
                throw new ArgumentNullException();
            }

            var appCounts = new Dictionary<string, uint>(manager.ApplicationPools.Count);
            foreach (var app in manager.Sites.SelectMany(site => site.Applications))
            {
                if (!appCounts.ContainsKey(app.ApplicationPoolName))
                {
                    appCounts.Add(app.ApplicationPoolName, 1);
                }
                else
                {
                    appCounts[app.ApplicationPoolName]++;
                }
            }

            return appCounts;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            while (!Console.KeyAvailable)
            {
                Console.WriteLine("Checking App Pools...");

                using (var manager = new ServerManager())
                {
                    var appCounts = manager.GetPoolApplicationCounts();

                    var appPools = manager.ApplicationPools.Where(pool => appCounts.ContainsKey(pool.Name));

                    foreach (
                        var pool in
                            appPools.Where(
                                pool => (pool.State != ObjectState.Started) && (pool.State != ObjectState.Starting)))
                    {
                        var state = pool.Start();

                        if ((state == ObjectState.Started) || (state == ObjectState.Starting))
                        {
                            Console.WriteLine("Started app pool \"{0}\"", pool.Name);
                        }
                        else
                        {
                            Console.WriteLine("Failed to start app pool \"{0}\". state:{1}", pool.Name, state);
                        }
                    }
                }

                Console.WriteLine("Sleeping...");
                Thread.Sleep(1000);
            }
        }
    }
}

WinDbg会话:

代码语言:javascript
复制
> !dumpheap -stat

606b778c      479         5748 System.Runtime.Remoting.Activation.ConstructionLevelActivator
00472088      480         5760 System.Collections.Generic.Dictionary`2+ValueCollection[[System.String, mscorlib],[Microsoft.Web.Administration.Interop.IAppHostElement, Microsoft.Web.Administration]]
00471d5c      480         5760 System.Collections.Generic.SortedList`2+ValueList[[System.String, mscorlib],[Microsoft.Web.Administration.Configuration, Microsoft.Web.Administration]]
00194568      481         5772 Web.Administration.LeakExample.Program+<>c__DisplayClass3
00198438      480         7680 Microsoft.Web.Administration.Interop.AppHostWritableAdminManager
0047199c      481         7696 System.Linq.Enumerable+<>c__DisplayClassf`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
606cc200      958        11496 System.Char
00471e2c      479        11496 System.Collections.Generic.SortedList`2+SortedListValueEnumerator[[System.String, mscorlib],[Microsoft.Web.Administration.Configuration, Microsoft.Web.Administration]]
0047090c      479        11496 System.Collections.Generic.List`1+Enumerator[[Microsoft.Web.Administration.Site, Microsoft.Web.Administration]]
004706f0      958        11496 Microsoft.Web.Administration.ConfigurationElementCollectionBase`1+<>c__DisplayClass4[[Microsoft.Web.Administration.Site, Microsoft.Web.Administration]]
00471aec      480        11520 System.Collections.Generic.List`1+Enumerator[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
0047041c      480        11520 System.Collections.Generic.List`1[[Microsoft.Web.Administration.Site, Microsoft.Web.Administration]]
00196d58      480        11520 System.Collections.Generic.List`1[[Microsoft.Web.Administration.Configuration, Microsoft.Web.Administration]]
004715cc      481        11544 System.Collections.Generic.List`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
0047103c     1437        17244 Microsoft.Web.Administration.ConfigurationElementCollectionBase`1+<>c__DisplayClass4[[Microsoft.Web.Administration.Application, Microsoft.Web.Administration]]
606ccfc8     1438        17256 System.Int32
00196a58      480        19200 System.Collections.Generic.SortedList`2[[System.String, mscorlib],[Microsoft.Web.Administration.Configuration, Microsoft.Web.Administration]]
0019660c      480        21120 Microsoft.Web.Administration.ConfigurationManager
00471130      958        22992 System.Collections.Generic.List`1+Enumerator[[Microsoft.Web.Administration.Application, Microsoft.Web.Administration]]
00470d68      960        23040 System.Collections.Generic.List`1[[Microsoft.Web.Administration.Application, Microsoft.Web.Administration]]
00198558      480        23040 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[Microsoft.Web.Administration.Interop.IAppHostElement, Microsoft.Web.Administration]]
00196a08      481        23088 Microsoft.Web.Administration.Configuration
00183170      481        23088 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.UInt32, mscorlib]]
606b7574      479        24908 System.Runtime.Remoting.Messaging.ConstructorCallMessage
00199e7c      479        24908 System.Linq.Enumerable+<SelectManyIterator>d__14`2[[Microsoft.Web.Administration.Site, Microsoft.Web.Administration],[Microsoft.Web.Administration.Application, Microsoft.Web.Administration]]
00199384      480        28800 System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[Microsoft.Web.Administration.Interop.IAppHostElement, Microsoft.Web.Administration]][]
00470874      958        30656 System.Predicate`1[[Microsoft.Web.Administration.Site, Microsoft.Web.Administration]]
004718a8      962        30784 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
001944d8      481        30784 Microsoft.Web.Administration.ServerManager
00195178      963        30816 System.Func`2[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration],[System.Boolean, mscorlib]]
606ccf90      968        31268 System.Int32[]
00197a50      480        32640 Microsoft.Web.Administration.SiteCollection
00194da0      481        32708 Microsoft.Web.Administration.ApplicationPoolCollection
004719f8     2874        34488 Microsoft.Web.Administration.ConfigurationElementCollectionBase`1+<>c__DisplayClass4[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
0019810c      960        42240 Microsoft.Web.Administration.ConfigurationSection
00471098     1437        45984 System.Predicate`1[[Microsoft.Web.Administration.Application, Microsoft.Web.Administration]]
606cc1c8      961        46638 System.Char[]
001838d0      481        59644 System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[System.UInt32, mscorlib]][]
606bedd0     5269        63228 System.UInt32
00470a7c      960        69120 Microsoft.Web.Administration.ApplicationCollection
00197c60      960        76800 Microsoft.Web.Administration.Site
00197ea8     1440        86400 Microsoft.Web.Administration.Application
00471a54     2874        91968 System.Predicate`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
6067c684     4832       141272 System.Object[]
00195024     2886       196248 Microsoft.Web.Administration.ApplicationPool
606c7b20    16323       261168 System.__ComObject

>.foreach (obj {!dumpheap -mt 001944d8 -short}){!gcroot -all obj}

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+70: 002ef148
            ->  02773270 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+68: 002ef150
            ->  02773270 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+78: 002ef140
            ->  027732c0 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+6c: 002ef14c
            ->  02773270 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+74: 002ef144
            ->  027732c0 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+60: 002ef158
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+3c: 002ef17c
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+4c: 002ef16c
            ->  027732c0 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+40: 002ef178
            ->  02773270 System.Linq.Enumerable+WhereEnumerableIterator`1[[Microsoft.Web.Administration.ApplicationPool, Microsoft.Web.Administration]]
            ->  02772948 Microsoft.Web.Administration.ApplicationPoolCollection
            ->  02772060 Microsoft.Web.Administration.ServerManager

    002ef124 003f0359 Web.Administration.LeakExample.Program.Main(System.String[]) [c:\Users\Chuck\Documents\Visual Studio 2012\Projects\Web.Administration.LeakExample\Web.Administration.LeakExample\Program.cs @ 74]
        ebp+50: 002ef168
            ->  02772060 Microsoft.Web.Administration.ServerManager

Found 10 roots.
EN

回答 3

Stack Overflow用户

发布于 2012-07-17 04:17:22

当我第一次读到这个问题时,我想到的第一件事是,整个问题都可能通过使用Windows Activation Service (WAS)来完全避免。

我第一次浏览您发布的代码时,感觉到您的问题可能与访问/修改由foreach循环创建的各种闭包有关。

尝试这些小重构,看看是否有/all能够减少或消除问题,或者如果失败,提供了有关根本原因的更多信息:

通过调用重用ServerManager对象的immediately

  • Instead of
  1. 来避免LINQ查询的延迟执行,在循环的每次迭代上创建一个新的
  2. 循环,因为您只使用了ApplicationPool.Name,重构如下:

foreach (var app in manager.Sites.SelectMany(site => site.Applications))

要这样做:

代码语言:javascript
复制
foreach (var app in manager.Sites.SelectMany(site => site.Applications, 
   (s, a) => a.Name)
    .ToList())

我的假设是这是正在发生的事情:

在对象引用上调用statement

  • Static扩展方法时,会立即在构造internally

  • ApplicationPools时再次使用
  • ,该IQueryable会立即使用(但不是完全执行-- foreach语句在内部使用yield return )并进行过滤。对.Start()
  • 调用会更改(变异).Start()对象引用的ApplicationPool的状态,而ServerManager对象rest并不相关,因此循环回到开始。它仍然使用相同的ServerManager。由于引用状态发生了变化(由于对.Start()的调用),它可能会被GC标记且永远不会被收集-该应用程序池永远不会在后续迭代的结果中返回,并可能导致内存中引用的孤立。

这只是一个假设,请记住!

票数 3
EN

Stack Overflow用户

发布于 2012-07-18 04:50:13

我现在相信这不是真正的泄密。我按照Josh的建议尝试了ToList()方法。这不会影响内存使用率。

我在循环中添加了一个GC.Collect() (仅用于测试),这样就消除了“泄漏”。我通过内存转储验证了这一点,如果我在堆上没有发现Web.Application对象。这与我在前面的转储中看到的所有只有一个Web.Application对象实际上是根对象的事实不谋而合。其他的没有根深蒂固,等待被收集。

我被.NET垃圾收集器的不确定性质给绊倒了。很抱歉弄出这么大的噪音。

票数 1
EN

Stack Overflow用户

发布于 2017-01-23 23:08:52

我在这里找到了解决方案:www.tomanderson.me

建议使用

代码语言:javascript
复制
using (ServerManager sm = ServerManager.OpenRemote("localhost"))
{ /*..*/ }

对我很管用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11509902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档