我正在使用.NET 3.5。證書內存泄漏
創建對X509Certificate的引用時遇到內存泄漏。我使用ANTS分析器來分析結果,並且私有字節正在增加,而堆中的字節保持靜態(表示由於非託管代碼導致的內存泄漏)。
我正在使用CRYPT32 DLL來管理證書。我打開一個對cert store的引用來獲得一個內部指針(intptr)的商店句柄。然後,我使用此存儲處理程序查找商店中的證書(本地保存)。獲得證書後,我關閉證書存儲並將證書返回給調用程序。我在certclosestore中使用了標誌0,它在關閉存儲被調用後保持打開的資源打開。我相信這是因爲它在這裏提到的是什麼導致了內存泄漏: 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;
}
謝謝您提供的內容豐富的答覆。你是對的,我不會在我的代碼中的任何地方調用CertFreeCertificateContext來釋放這個資源。在X509Certificate返回證書之後,我會給它一個提示,希望你能夠在創建它之後釋放它。 – CorribView 2012-08-16 13:04:46
它的工作原理:-) 感謝您的解決方案!我正在研究這一段時間,認爲我仍然會在沒有您的輸入的情況下盯着代碼。 – CorribView 2012-08-16 14:18:19