【问题标题】:Memory leak with dynamic code in COM InteropCOM 互操作中动态代码的内存泄漏
【发布时间】:2012-05-20 10:34:05
【问题描述】:

出于旧版 ASP 代码和新 ASP.NET 代码之间的兼容性原因,我们有一堆 .NET COM 对象,它们将我们的一些 .NET 实用程序暴露给 ASP。在某些情况下,我们需要在 .NET COM 包装器中使用另一个 COM 对象。为了实现高灵活性并避免 PIA 依赖性,我们决定使用动态代码来处理这些 COM 对象。

简化的 C# COM 对象:

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace TestCom
{
    [ComVisible(true)]
    [Guid("6DC92920-8C3C-4C81-A615-BD0E3A332024")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface ITestComObject
    {
        [DispId(1)]
        string MyMethod(dynamic dictionary);
    }

    [ComVisible(true)]
    [Guid("F52A463E-F03B-4703-860C-E86CDD6D04E3")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("TestCom.TestComObject")]
    public class TestComObject : ITestComObject
    {
        string ITestComObject.MyMethod(dynamic dictionary)
        {
            StringBuilder sb = new StringBuilder();

            if (dictionary != null)
            {
                foreach (object key in dictionary)
                {
                    object p = dictionary[key];
                    if (p != null)
                    {
                        sb.AppendFormat("{0}={1}{2}", key, p, Environment.NewLine);
                    }
                }
            }

            return sb.ToString();
        }
    }
}

测试 ASP 页面:

<%@ Language=VBScript %>
<%
    Dim testObj, params
    Set testObj = Server.CreateObject("TestCom.TestComObject")

    Set params = Server.CreateObject("Scripting.Dictionary")
    params("lang") = "en-US"
    params("num") = 42

    Response.Write testObj.MyMethod(params)

    Set testObj = Nothing
    Set params = Nothing
%>

在正常情况下,动态代码只会编译一次,随后的调用会重用它。然而,在我们的例子中,动态代码似乎是在每次调用时编译的。当我将内存分析器附加到 IIS 进程时,我可以清楚地看到来自 Microsoft.CSharp.RuntimeBinder.Semantics 命名空间的其他对象出现在 gen2 中。这有效地导致了我们的 IIS 进程中的内存泄漏。

任何想法如何解决这个动态代码编译问题?请注意,在我们的案例中,重写所有代码以使用 PIA 和 COM 接口并不总是一种选择。

【问题讨论】:

    标签: c#-4.0 dynamic asp-classic memory-leaks com-interop


    【解决方案1】:

    我建议您将任何易受内存泄漏影响的代码作为单独的进程 - 例如,父进程通过套接字与此类泄漏进程通信。然后要么在每次通话时重新启动这些泄漏进程,要么在晚上的某个时间重新启动它们!

    【讨论】:

    • 规范:您的建议在我们使用 ASP 和 COM 互操作的情况下并不真正有效。另外我不认为忽略内存泄漏并重新启动进程在原则上是可以接受的。
    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多