Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模拟内存泄漏_C#_Asp.net_Winapi_Memory Leaks - Fatal编程技术网

C# 模拟内存泄漏

C# 模拟内存泄漏,c#,asp.net,winapi,memory-leaks,C#,Asp.net,Winapi,Memory Leaks,上有一个关于如何使用.net 4.0进行模拟的示例。为了便于使用,我们在继承IDisposable的类中使用了这个示例。然而,当我们在asp.net web应用程序中使用此类时,我们注意到performance monitor中的池分页字节有轻微但稳定的增加。一周后,应用程序崩溃 我尝试了模拟类的不同实现,使用和作为引用,但它们都显示了相同的漏洞 这个漏洞是从哪里来的?windows api有问题吗?我们正在运行Windows 2008 R2 这是模拟类的当前版本: public class I

上有一个关于如何使用.net 4.0进行模拟的示例。为了便于使用,我们在继承IDisposable的类中使用了这个示例。然而,当我们在asp.net web应用程序中使用此类时,我们注意到performance monitor中的池分页字节有轻微但稳定的增加。一周后,应用程序崩溃

我尝试了模拟类的不同实现,使用和作为引用,但它们都显示了相同的漏洞

这个漏洞是从哪里来的?windows api有问题吗?我们正在运行Windows 2008 R2

这是模拟类的当前版本:

public class Impersonator : IDisposable
{
    public Impersonator(string username, string domain, string password)
    {
        if (!ImpersonateValidUser(username, domain, password))
        {
            throw new SecurityException("Could not impersonate. Wrong username / password");
        }
    }

    public void Dispose()
    {
        UndoImpersonation();
    }

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    private const int LOGON32_PROVIDER_DEFAULT = 0;
    private const int LOGON32_LOGON_INTERACTIVE = 2; //This parameter causes LogonUser to create a primary token.

    private WindowsImpersonationContext impersonatedUser;

    private bool ImpersonateValidUser(string username, string domain, string password)
    {
        SafeTokenHandle safeTokenHandle;

        // Call LogonUser to obtain a handle to an access token.
        bool success = LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);

        if (success)
        {
            using (safeTokenHandle)
            {
                // Use the token handle returned by LogonUser.
                WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
                impersonatedUser = newId.Impersonate();
            }
        }

        return success;
    }

    private void UndoImpersonation()
    {
        // Releasing the context object stops the impersonation
        if (impersonatedUser != null)
        {
            impersonatedUser.Undo();
            impersonatedUser.Dispose();
        }
    }
}

public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle() : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}
这是使用该类不同版本的两个Web服务器的性能监视器图:

当我们禁用该类并通过web.config使用全局模拟时,这些行是完全平坦的


更新

我已经做了一个测试应用程序,成功地重现了这个问题。可在此下载:

超过18小时的结果如下所示:


很难说。至少,
WindowsIdentity
本身也是一个
IDisposable
,而且
newId
变量永远不会被处理掉。此外,我还要检查是否正确地处理了
模拟程序
类的所有使用。

该类的所有使用都是在using语句中进行的,因此应该是安全的。虽然newId变量调用得很好,但我会修复它并将其发送给明天的测试。更新的结果相同。我还在我们的开发环境中制作了一个测试应用程序,但我似乎无法复制那里的漏洞。经过100万次模拟后,池分页字节保持不变,因此我真的不知道从这里走到哪里。我也不知所措。如果没有额外的信息(并且考虑到场景,最有可能是:没有完整的应用程序),就无法判断。我几乎不希望处理WindowsIdentity会起到什么作用,但是,唉,我现在已经成功地复制了漏洞,现在在我的问题中找到了完整的应用程序。在我更改了测试应用程序以更好地复制生产环境的行为(在模拟过程中在网络共享上创建和删除文件)之后,我已经看过你的代码和SafeHandleZeroOrMinusOneIsInvalid(通过Reflector)的实现。我肯定我可能错过了一些东西,但我不清楚CloseHandle或ReleaseHandle是从哪里调用的。您是否希望由SafeTokenHandle上继承的Dispose方法调用它?我不知道它是如何工作的,我只是假设它是这样的,因为它是从上面链接中的microsoft站点复制的。我添加了几行调试,模拟完成后会调用它,但我只知道这些。考虑到您所说的以及其他示例显式关闭句柄,那么这似乎不是问题。你有MSDN订阅吗?如果是这样的话,您可以利用Microsoft支持事件获得一些额外的帮助。是的,我们有MSDN订阅,但由于我似乎无法在本地重现问题,我认为这不会有帮助。尽管如此,我更新了我的问题,提供了有关如何重现泄漏的信息。