I'm new to .NET development, but have been a programmer for 16 years, so I'm not new to coding. I developed this code as a C# COM object (dll) for a lotus notes application. The COM Object gets instantiated, and I pass the encoded data to the objects "CertificationData" attribute. It then loops through 4000+ records and calls the "GetCertExpirationDate" method for each record, passing in the "CertificationData" attribute as Bytes. After some investigating I noticed the X509Certificate object takes 4 seconds to be created. Everything else including the interop takes milliseconds to complete. I noticed when I first installed the code it ran at warp speed, then degraded over time to the 4 seconds I see now. I'm worried the object may have a memory leak. How can I make sure the object is removed, and memory cleared? Deos anybody have example code that would allow me to make sure there are no memory leaks? I've tried a few things that I've commented out. I've been hitting my head against a stone wall for days. I'm stuck, and need help! Heres my code mentioned above:
using System; using System.IO; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Runtime.InteropServices; //Need for API namespace CertificationInfo { //Certification Class public class CertificateInformation { //Class Attributes public string CertificateData; public string ExpirationDate; public string NotesUNID; public Boolean LoggingOn; public String LogFile; public Boolean ErrLoggingOn; public String ErrFile; private MemoryManagement MemMngr; private DLLLog Logging; private String DateString; //Constructor public CertificateInformation() { //Reset Expiration Date this.ExpirationDate = ""; this.LoggingOn = false; this.ErrLoggingOn = false; DateTime TodaysDate = DateTime.Today; this.DateString = (TodaysDate.Year.ToString())+(TodaysDate.Month.ToString())+(TodaysDate.Day.ToString()); this.LogFile = "DLLLog"+this.DateString+".txt"; this.ErrFile = "DLLErrors"+this.DateString+".txt"; this.MemMngr = new MemoryManagement(); this.Logging=new DLLLog(); } //Method public string GetCertExpirationDate(string rawdata) { try { this.Logging.LogMe(this.LogFile, "Start Logging - UNID: "+this.NotesUNID,this.LoggingOn); //Clean Up Memory //this.MemMngr.ReleaseMemory(); //Reset Expiration Date Property this.ExpirationDate = ""; //Check for data if (rawdata == "" && this.CertificateData == "") { this.Logging.LogMe(this.LogFile, "Variables rawdata and certificatedata blank!", this.LoggingOn); //Nothing is passed & property is blank this.ExpirationDate = ""; } else { //Check for Raw Data value if (rawdata != "") { this.Logging.LogMe(this.LogFile, "Using variable rawdata!", this.LoggingOn); this.CertificateData = rawdata; } //Convert Property Array //Might be best to use unicode Under Encoding namespace //System.Text.UnicodeEncoding Encoding=new System.Text.UnicodeEncoding(); //Byte[] bytedata=Encoding.GetBytes(this.CertificateData); this.Logging.LogMe(this.LogFile, "Converting Cert Data: " + this.CertificateData, this.LoggingOn); //Convert Property to byte array System.Text.ASCIIEncoding Encoding = new System.Text.ASCIIEncoding(); Byte[] bytedata = Encoding.GetBytes(this.CertificateData); this.Logging.LogMe(this.LogFile, "Cert Data Converted!", this.LoggingOn); //Create Encoding Object this.Logging.LogMe(this.LogFile, "Creating X509 Object...", this.LoggingOn); X509Certificate CertificateObject = new X509Certificate(bytedata); //X509Certificate2 CertificateObject = new X509Certificate2(bytedata); //this.CertificateObject = new X509Certificate(bytedata); this.Logging.LogMe(this.LogFile, "X509 Object Created!", this.LoggingOn); //Might have to check to see iff cert object is null though catch should pick it up //Get Expiration date //this.ExpirationDate = CertificateObject.GetExpirationDateString(); this.Logging.LogMe(this.LogFile, "Get expirationdate...", this.LoggingOn); this.ExpirationDate = CertificateObject.GetExpirationDateString(); this.Logging.LogMe(this.LogFile, "Expiration Date: " + this.ExpirationDate, this.LoggingOn); //Reset Object & Certificate Data Property //this.Logging.LogMe("DLLLog", "Nulling Out Objects!"); //CertificateObject = null; //Encoding = null; //this.Logging.LogMe("DLLLog", "Resetting Certificate..."); //CertificateObject.Reset(); //this.CertificateData = ""; //Clean Up Memory //this.Logging.LogMe("DLLLog", "Memory Manager Clean-up!"); //this.MemMngr.ReleaseMemory(); } } //Error Trapping in case of error still returns something catch { this.Logging.LogMe(this.ErrFile, "Start Error Logged - UNID: " + this.NotesUNID, this.ErrLoggingOn); this.Logging.LogMe(this.ErrFile, "Error Data -: " + this.CertificateData, this.ErrLoggingOn); this.Logging.LogMe(this.ErrFile, "End Error Logged - UNID: " + this.NotesUNID, this.ErrLoggingOn); this.ExpirationDate = ""; } //this.Logging.LogMe("DLLLog", "Returning expiration date!"); this.Logging.LogMe(this.LogFile, "End Logging - UNID: " + this.NotesUNID + " Returning expiration date!", this.LoggingOn); return this.ExpirationDate; } } //Debug Log Code public class DLLLog { //Constructor public DLLLog() { } //Methods public void LogMe(String Filename,String LogMeMessage,Boolean LogOn) { if (LogOn==true) { using (StreamWriter w = File.AppendText(Filename)) { WriteLog(LogMeMessage, w); } } } public static void WriteLog(string logMessage,TextWriter w) { w.Write("\r\nLog Entry: "); w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString()); //w.WriteLine(" :"); w.WriteLine(" :{0}", logMessage); w.WriteLine("-------------------------------"); } public static void ReadLog(StreamReader r) { string line; while ((line = r.ReadLine()) != null) { Console.WriteLine(line); } } } //API Class to Clean up Memory threads public class MemoryManagement { //Memory Management API [DllImport("kernel32.dll")] public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max); //Method public void ReleaseMemory() { GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); } } } }