我正在使用.NET 3.5.创建对X509Certificate的引用时遇到内存泄漏.我正在使用ANTS事件探查器来分析结果,并且专用字节在增加,而堆中的字节保持静态(指示由于未托管代码而导致的内存泄漏).我正在使用CRYPT32 dll管理证...
我正在使用.NET 3.5.
创建对X509Certificate的引用时遇到内存泄漏.我正在使用ANTS事件探查器来分析结果,并且专用字节在增加,而堆中的字节保持静态(指示由于未托管代码而导致的内存泄漏).
我正在使用CRYPT32 dll管理证书.我打开对证书存储的引用以获取作为内部指针(intptr)的存储句柄.然后,我使用此商店处理程序在商店中找到证书(本地保存).拥有证书后,我将关闭证书存储并将证书返回到调用程序.我在certclosestore中使用标志0,该标志在调用close存储后使开放资源保持打开状态.我相信这就是导致内存泄漏的原因,如下所述:
http://msdn.microsoft.com/en-us/library/ms937035.aspx
但是,当我将关闭标志更改为:
CertCloseStore(storeHandle, 2)
应该释放出分配的资源.但是,这只会导致服务爆炸.
该应用程序的工作方式是验证证书等.唯一的问题是内存使用量正在缓慢增加,并且需要每周左右重新启动该服务.任何想法或想法将不胜感激.
public static X509Certificate CreateFromRegistry(string certificateIdent)
{
X509Certificate certificate = null;
IntPtr storeHandle = CertificateStore.CertOpenStore(CERT_STORE_PROV_SYSTEM,
0, 0,CERT_SYSTEM_STORE_LOCAL_MACHINE, "MY");;
certificate = new X509Certificate(CertificateStore.
FindCertInStore(certificateIdent, storeHandle));
CertificateStore.CertCloseStore(storeHandle, 0);
return certificate;
}
public class CertificateStore
{
const int CERT_STORE_PROV_SYSTEM = 10;
private static int CERT_SYSTEM_STORE_LOCAL_MACHINE = (2 << 16);
const uint PKCS_7_ASN_ENCODING = 0x00010000;
const uint X509_ASN_ENCODING = 0x00000001;
const uint CERT_FIND_SUBJECT_STR = 0x00080007;
const uint CERT_FIND_ISSUER_STR = 0x00080004;
static uint MY_ENCODING_TYPE = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
[DllImport("CRYPT32", EntryPoint = "CertOpenStore",
CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr CertOpenStore(
int storeProvider, int encodingType,
int hcryptProv, int flags, string pvPara);
[DllImport("CRYPT32", EntryPoint = "CertCloseStore",
CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CertCloseStore(
IntPtr storeProvider,
int flags);
}
public static X509Certificate FindCertInStore
(string trustedRootIssuerName, IntPtr storeHandle)
{
IntPtr hCertCntxt;
X509Certificate theActualCertificate = null;
if (storeHandle != IntPtr.Zero)
{
hCertCntxt = CertFindCertificateInStore(
storeHandle,
MY_ENCODING_TYPE,
0,
CERT_FIND_ISSUER_STR,
trustedRootIssuerName,
IntPtr.Zero);
if (hCertCntxt != IntPtr.Zero)
{
theActualCertificate = new X509Certificate(hCertCntxt);
}
}
return theActualCertificate;
}
解决方法:
好吧,您当然正在泄漏CRYPT32资源.我在您的代码段中看到的一个直接候选对象是CertFindCertificateInStore()的返回值.它必须通过对CertFreeCertificateContext()的显式调用来释放,我看不到.
X509Certification(IntPtr)构造函数的文档记录得不好,它没有描述上下文需要有效的时间.我看到它调用了一个名为X509Utils._DuplicateCertContext()的内部方法,因此发生机率很高,您可以在创建对象后立即调用发布函数.
请使用细齿梳检查代码的其余部分,并三重检查是否释放了从CRYPT32获得的所有句柄和指针.
本文标题为:C#-证书内存泄漏
基础教程推荐
- c#实现爬虫程序 2023-05-26
- C#可变参数params示例详解 2023-05-17
- c#使用FreeSql生产环境时自动升级备份数据库 2023-04-21
- c# 实现位图算法(BitMap) 2023-03-09
- C#创建Excel多级分组的方法 2022-12-02
- C#导航器Xpath与XPathNavigator类 2023-06-09
- 如何使用C#代码创建快捷方式文件详解 2022-12-31
- C#使用Chart绘制曲线 2023-05-22
- C#使用DirectX.DirectSound播放语音 2023-05-26
- C# Socket通信的实现(同时监听多客户端) 2023-04-14