possible memory leak? - c#

i'm profiling the below code inside a singltone and found that a lot of Rate objects are kept in memory altough i clear them.
protected void FetchingRates()
{
int count = 0;
while (true)
{
try
{
if (m_RatesQueue.Count > 0)
{
List<RateLog> temp = null;
lock (m_RatesQueue)
{
temp = new List<RateLog>();
temp.AddRange(m_RatesQueue);
m_RatesQueue.Clear();
}
foreach (RateLog item in temp)
{
m_ConnectionDataAccess.InsertRateLog(item);
}
temp.Clear();
temp = null;
}
count++;
Thread.Sleep(int.Parse(ConfigurationManager.AppSettings["RatesIntreval"].ToString()));
}
catch (Exception ex)
{
}
}
}
the insertion to the queue is made by:
public void InsertLogRecord(RateLog msg)
{
try
{
if (m_RatesQueue != null)
{
//lock (((ICollection)m_queue).SyncRoot)
lock (m_RatesQueue)
{
//insert new job to the line and release the thread to continue working.
m_RatesQueue.Add(msg);
}
}
}
catch (Exception ex)
{
}
}
the worker inserts rate log into DB as follows:
internal int InsertRateLog(RateLog item)
{
try
{
SqlCommand dbc = GetStoredProcCommand("InsertRateMonitoring");
if (dbc == null)
return 0;
dbc.Parameters.Add(new SqlParameter("#HostName", item.HostName));
dbc.Parameters.Add(new SqlParameter("#RateType", item.RateType));
dbc.Parameters.Add(new SqlParameter("#LastUpdated", item.LastUpdated));
return ExecuteNonQuery(dbc);
}
catch (Exception ex)
{
return 0;
}
}
any one sees a possible memory leak?

Stopping swallowing all exceptions would be the first place to start I would suggest.

You are certainly clearing the queue and the temporary list temp (which is unnecessary since it is eligible for collection even before you assign null to the reference). At this point I think your problem is more likely related to the following line.
m_ConnectionDataAccess.InsertRateLog(item);
You are passing a reference to a RateLog to another method. You have not provided any details on this method so I cannot eliminate the possibility that it is storing its own copy of the reference in a separate data structure.

I have experienced the same issue. There is probably a real explanation for this, but I couldn't find it.
I assumed that because I was in a while(true) loop the GC won't run. I don't know if this is an artefact of MS's implementation of the .NET framework (.NET 3.5), but it is what I experienced.
The way I mitigated the memory pile up was by putting GC.Collect(); at the bottom of the loop.
I have a feeling it was something to do with undisposed SqlConnection objects.

There is no need in clearing and nulling of List<RateLog> temp. It will be collected by GC anyway because leaving from function scope with lack of references, i.e. there is no more references to this variable on function end so it will be collected.

Related

C# Enqueue Failure

I have a simple logging mechanism that should be thread safe. It works most of the time, but every now and then I get an exception on this line, "_logQ.Enqueue(s);" that the queue is not long enough. Looking in the debugger there are sometimes just hundreds of items, so I can't see it being resources. The queue is supposed to expand as needed. If I catch the exception as opposed to letting the debugger pause at the exception I see the same error. Is there something not thread safe here? I don't even know how to start debugging this.
static void ProcessLogQ(object state)
{
try
{
while (_logQ.Count > 0)
{
var s = _logQ.Dequeue();
string dir="";
Type t=Type.GetType("Mono.Runtime");
if (t!=null)
{
dir ="/var/log";
}else
{
dir = #"c:\log";
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
if (Directory.Exists(dir))
{
File.AppendAllText(Path.Combine(dir, "admin.log"), DateTime.Now.ToString("hh:mm:ss ") + s + Environment.NewLine);
}
}
}
catch (Exception)
{
}
finally
{
_isProcessingLogQ = false;
}
}
public static void Log(string s) {
if (_logQ == null)
_logQ = new Queue<string> { };
lock (_logQ)
_logQ.Enqueue(s);
if (!_isProcessingLogQ) {
_isProcessingLogQ = true;
ThreadPool.QueueUserWorkItem(ProcessLogQ);
}
}
Note that the threads all call Log(string s). ProcessLogQ is private to the logger class.
* Edit *
I made a mistake in not mentioning that this is in a .NET 3.5 environment, therefore I can't use Task or ConcurrentQueue. I am working on fixes for the current example within .NET 3.5 constraints.
** Edit *
I believe I have a thread-safe version for .NET 3.5 listed below. I start the logger thread once from a single thread at program start, so there is only one thread running to log to the file (t is a static Thread):
static void ProcessLogQ()
{
while (true) {
try {
lock (_logQ);
while (_logQ.Count > 0) {
var s = _logQ.Dequeue ();
string dir = "../../log";
if (!Directory.Exists (dir))
Directory.CreateDirectory (dir);
if (Directory.Exists (dir)) {
File.AppendAllText (Path.Combine (dir, "s3ol.log"), DateTime.Now.ToString ("hh:mm:ss ") + s + Environment.NewLine);
}
}
} catch (Exception ex) {
Console.WriteLine (ex.Message);
} finally {
}
Thread.Sleep (1000);
}
}
public static void startLogger(){
lock (t) {
if (t.ThreadState != ThreadState.Running)
t.Start ();
}
}
private static void multiThreadLog(string msg){
lock (_logQ)
_logQ.Enqueue(msg);
}
Look at the TaskParallel Library. All the hard work is already done for you. If you're doing this to learn about multithreading read up on locking techniques and pros and cons of each.
Further, you're checking if _logQ is null outside your lock statement, from what I can deduce it's a static field that you're not initializing inside a static constructor. You can avoid doing this null check (which should be inside a lock, it's critical code!) you can ensure thread-safety by making it a static readonly and initializing it inside the static constructor.
Further, you're not properly handling queue states. Since there's no lock during the check of the queue count it could vary on every iteration. You're missing a lock as your dequeuing items.
Excellent resource:
http://www.yoda.arachsys.com/csharp/threads/
For a thread-safe queue, you should use the ConcurrentQueue instead:
https://msdn.microsoft.com/en-us/library/dd267265(v=vs.110).aspx

Monitor.TryEnter / Monitor.Exit and SynchronizationLockException

Is it possible to detect if the same thread trying to release the lock?
We have many places in code that looks like:
try
{
try
{
if(!Monitor.TryEnter(obj, 2000))
{
throw new Exception("can not lock");
}
}
finally
{
Monitor.Exit(obj);
}
}
catch
{
//Log
}
The above code very simplified, and actually Enter and Exit statement located in custom object (lock manager).
The problem, that in that structure, we have SynchronizationLockException when trying to "Exit", since it looks like the thread that not succeed to lock, tries to release in finally.
So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?
I thought that I can use CurrentThread.Id to sync enter and exit, but I'm not sure if it "safe" enough.
So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?
You can't, easily, as far as I'm aware. You can't find out which thread owns a monitor.
However, this is just a coding issue - you should change your code so that it doesn't even attempt to release the monitor when it shouldn't. So your code above could be rewritten as:
if (!Monitor.TryEnter(obj, 2000))
{
throw new Exception(...);
}
try
{
// Presumably other code
}
finally
{
Monitor.Exit(obj);
}
Or even better, if you're using .NET 4, use the overload of TryEnter which accepts an ret parameter:
bool gotMonitor = false;
try
{
Monitor.TryEnter(obj, ref gotMonitor);
if (!gotMonitor)
{
throw new Exception(...);
}
// Presumably other code
}
finally
{
if (gotMonitor)
{
Monitor.Exit(obj);
}
}
As you think that to put the calling of Monitor.Exit in try-catch was 'durty'(dirty?), here's a very simple idea trying to 'take the durty away'. Lock is reentrant for the same thread and if one thread acquired successfully, before it releases, attempt from another thread will fail. So that you can consider something like:
public void Exit(object key) {
if(!IsActive) {
return;
}
if(LockDictionary.ContainsKey(key)) {
var syncObject=LockDictionary[key];
if(Monitor.TryEnter(syncObject.SyncObject, 0)) {
SetLockExit(syncObject);
Monitor.Exit(syncObject.SyncObject);
Monitor.Exit(syncObject.SyncObject);
}
}
}
We call Monitor.Exit twice because we lock it twice, one in the code outer, and one just here.
I know this is an older question, but here's my answer anyway.
I would move the try-finally construct inside the if:
try
{
if(Monitor.TryEnter(obj, 2000))
{
try
{
// code here
}
finally
{
Monitor.Exit(obj);
}
}
else
{
throw new Exception("Can't acquire lock");
}
}
catch
{
// log
}

C# -My application and Interopability (DLL/COM) with an external application

I've been developing a C# application that uses DLL interop to an external database application.
This external app starts up at the same time along with my C# app and is available as long as my C# app is running.
Now the real question is related to managing the objects that I need to create to interact with the external application.
When I declare objects that are available from the referenced DLL's these objects have methods that operate with files (that are proprietary) and run some queries (like if did it by this external app GUI). These objects are destroyed "by me" using Marshal.ReleaseComObject(A_OBJECT) while others run in a diferent application domain, by using AppDomain.CreateDomain("A_DOMAIN"), do the operations and call an AppDomain.Unload("A_DOMAIN"), releasing the DLLs used for the operation...
These workarounds are made to ensure that this external application doesn't "block" files used in these operations, therefore allowing deletion or moving them from a folder.
e.g.
private static ClientClass objApp = new ClientClass();
public bool ImportDelimitedFile(
string fileToImport,
string outputFile,
string rdfFile)
{
GENERICIMPORTLib import = new GENERICIMPORTLibClass();
try
{
import.ImportDelimFile(fileToImport, outputFile, 0, "", rdfFile, 0);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(import);
import = null;
}
}
public int DbNumRecs(string file)
{
if (!File.Exists(file))
{
return -1;
}
System.AppDomain newDomain = System.AppDomain.CreateDomain();
COMMONIDEACONTROLSLib db = new COMMONIDEACONTROLSLibClass();
try
{
db = objApp.OpenDatabase(file);
int count = (int)db.Count;
db.Close();
objApp.CloseDatabase(file);
return count;
}
catch (Exception ex)
{
return -1;
}
finally
{
System.AppDomain.Unload(newDomain);
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
Both of these "solutions" were reached by trial and error, due to the fact I do not possess any kind of API manual. Are these solutions correct? Can you explain me the differences? Do I really need to work with both solutions or one should suffice?
Thanks!
Your use of AppDomains is wrong. Just because you create a new AppDomain before line X doesn't mean that line X is actually executing in that AppDomain.
You need to marshall a proxy class back across your AppDomain and use it in the current one.
public sealed class DatabaseProxy : MarshallByRefObject
{
public int NumberOfRecords()
{
COMMONIDEACONTROLSLib db = new COMMONIDEACONTROLSLibClass();
try
{
db = objApp.OpenDatabase(file);
int count = (int)db.Count;
db.Close();
objApp.CloseDatabase(file);
return count;
}
catch (Exception ex)
{
return -1;
}
}
}
and
public int NumberOfRecords()
{
System.AppDomain newDomain = null;
try
{
newDomain = System.AppDomain.CreateDomain();
var proxy = newDomain.CreateInstanceAndUnwrap(
typeof(DatabaseProxy).Assembly.FullName,
typeof(DatabaseProxy).FullName);
return proxy.NumberOfRecords();
}
finally
{
System.AppDomain.Unload(newDomain);
}
}
You can actually create an marshall back the COM object itself instead of instantiating it via your proxy. This code is completely written here and not tested, so may be buggy.
The first solution is the best one. Unmanaged COM uses a reference-counting scheme; IUnknown is the underlying reference-counting interface: http://msdn.microsoft.com/en-us/library/ms680509(VS.85).aspx. When the reference count reaches zero, it is freed.
When you create a COM object in .NET, a wrapper is created around the COM object. The wrapper maintains a pointer to the underlying IUnknown. When garbage collection occurs, the wrapper will call the underlying IUnknown::Release() function to free the COM object during finalization. As you noticed, the problem is that sometimes the COM object locks certain critical resources. By calling Marshal.ReleaseComObject, you force an immediate call to IUnknown::Release without needing to wait (or initiate) a general garbage collection. If no other references to the COM object are held, then it will immediately be freed. Of course, the .NET wrapper becomes invalid after this point.
The second solution apparently works because of the call to GC.Collect(). The solution is more clumsy, slower, and less reliable (the COM object might not necessarily be garbage collected: behavior is dependent on the specific .NET Framework version). The use of AppDomain contributes nothing as your code doesn't actually do anything apart from creating an empty domain and then unloading it. AppDomains are useful for isolating loaded .NET Framework assemblies. Because unmanaged COM code is involved, AppDomains won't really be useful (if you need isolation, use process isolation). The second function can probably be rewritten as:
public int DbNumRecs(string file) {
if (!File.Exists(file)) {
return -1;
}
// don't need to use AppDomain
COMMONIDEACONTROLSLib db = null; // don't need to initialize class here
try {
db = objApp.OpenDatabase(file);
return (int)db.Count;
} catch (Exception) } // don't need to declare unused ex variable
return -1;
} finally {
try {
if (db != null) {
db.Close();
Marshal.ReleaseComObject(db);
}
objApp.CloseDatabase(file); // is this line really needed?
} catch (Exception) {} // silently ignore exceptions when closing
}
}

try/catch + using, right syntax

Which one:
using (var myObject = new MyClass())
{
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
}
OR
try
{
using (var myObject = new MyClass())
{
// something here...
}
}
catch(Exception ex)
{
// Handle exception
}
I prefer the second one. May as well trap errors relating to the creation of the object as well.
Since a using block is just a syntax simplification of a try/finally (MSDN), personally I'd go with the following, though I doubt it's significantly different than your second option:
MyClass myObject = null;
try
{
myObject = new MyClass();
//important stuff
}
catch (Exception ex)
{
//handle exception
}
finally
{
if (myObject is IDisposable)
{
myObject.Dispose();
}
}
It depends. If you are using Windows Communication Foundation (WCF), using(...) { try... } will not work correctly if the proxy in using statement is in exception state, i.e. Disposing this proxy will cause another exception.
Personally, I believe in minimal handling approach, i.e. handle only exception you are aware of at the point of execution. In other word, if you know that the initialization of a variable in using may throw a particular exception, I wrap it with try-catch. Similarly, if within using body something may happen, which is not directly related to the variable in using, then I wrap it with another try for that particular exception. I rarely use Exception in my catches.
But I do like IDisposable and using though so I maybe biased.
If your catch statement needs to access the variable declared in a using statement, then inside is your only option.
If your catch statement needs the object referenced in the using before it is disposed, then inside is your only option.
If your catch statement takes an action of unknown duration, like displaying a message to the user, and you would like to dispose of your resources before that happens, then outside is your best option.
Whenever I have a scenerio similar to this, the try-catch block is usually in a different method further up the call stack from the using. It is not typical for a method to know how to handle exceptions that occur within it like this.
So my general recomendation is outside—way outside.
private void saveButton_Click(object sender, EventArgs args)
{
try
{
SaveFile(myFile); // The using statement will appear somewhere in here.
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
}
}
Both are valid syntax. It really comes down to what you want to do: if you want to catch errors relating to creating/disposing the object, use the second. If not, use the first.
There is one important thing which I'll call out here: The first one will not catch any exception arising out of calling the MyClass constructor.
From C# 8.0 on, you can simplify using statements under some conditions to get rid of the nested block, and then it just applies to the enclosing block.
So your two examples can be reduced to:
using var myObject = new MyClass();
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
And:
try
{
using var myObject = new MyClass();
// something here...
}
catch(Exception ex)
{
// Handle exception
}
Both of which are pretty clear; and then that reduces the choice between the two to a matter of what you want the scope of the object to be, where you want to handle instantiation errors, and when you want to dispose of it.
If the object you are initializing in the Using() block might throw any exception then you should go for the second syntax otherwise both the equally valid.
In my scenario, I had to open a file and I was passing filePath in the constructor of the object which I was initializing in the Using() block and it might throw exception if the filePath is wrong/empty. So in this case, second syntax makes sense.
My sample code :-
try
{
using (var obj= new MyClass("fileName.extension"))
{
}
}
catch(Exception ex)
{
//Take actions according to the exception.
}
From C# 8.0, I prefer to use the second one same like this
public class Person : IDisposable
{
public Person()
{
int a = 0;
int b = Id / a;
}
public int Id { get; set; }
public void Dispose()
{
}
}
and then
static void Main(string[] args)
{
try
{
using var person = new Person();
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType == System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Constructor Person");
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType != System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Person");
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
finally
{
Debug.Write("finally");
}
}

try finally mystery

Consider,
static void Main(string[] args)
{
Console.WriteLine(fun());
}
static int fun()
{
int i = 0;
try
{
i = 1;
return i;
}
catch (Exception ex)
{
i = 2;
return i;
}
finally
{
i = 3;
}
}
The sample code outputs "1". but the value of i is changed to 3 in finally block. Why wasn't the value of 'i' changed to 3?
Thank you,
Consider this code- I think the code explains what you are thinking, and how you can make what you think should happen actually happen:
static void Main(string[] args)
{
int counter = 0;
Console.WriteLine(fun(ref counter)); // Prints 1
Console.WriteLine(counter); // Prints 3
}
static int fun(ref int counter)
{
try
{
counter = 1;
return counter;
}
finally
{
counter = 3;
}
}
With this code you return 1 from the method, but you also set the counter variable to 3, which you can access from outside the method.
You have to remember that finally executes after everything else in the try and catch. Place the return statement after the try/catch/finally statement to have it return 3.
I imagine if you use a reference type instead of a value type you'd get different behavior.
When you said "return i"... C# puts that return value in a temporary holding area (memory) and then runs your 'finally' code... if the finally block was able to modify that value, it would defeat the safety/finalism of the finally block.
It's like a using statement with a return inside... the "Dispose" is still going to happen, AFTER the return (so to speak).
Finally is always executed
Your code always executes finally no matter if an exception was thrown or not. So your code should actually be:
try
{
i = 1;
}
catch
{
i = 2;
}
finally
{
i = 3;
}
return i;
But in this trivial case finally block won't make much sense. Because we will always return 3 no matter what happened before that.
Finally is used to release resources
finally block should normally be used when you have to release some system resources allocated within try block (ie. openning a DB connection an reading data in try block and closing it in finally). So they will always get released no matter if there was an exception or not. In this case it doesn't make much sense to use finally block.

Categories

Resources