Why do bitmaps stay in memory unless I call GC.Collect? - c#

I'm developing an application that connects to a GigEVision camera, and pulls images from it. I'm currently using the Pleora eBus SDK with C#.NET.
The code below is just a test application for the camera connection - it can stream images, but rapidly runs out of memory unless I call GC.Collect();
It's worth noting the images being streamed are large (4096x3072), so the crash happens fairly quickly.
I suspected at first that not calling Dispose() was the issue. However, I can call Dispose() on each image right before getting rid of the reference to it, and that did not fix the issue.
I've also tried explicitly releasing the buffers that come into the display thread callback, but that had no effect.
Can I get my memory back in a more elegant way?
using System;
using System.Windows.Forms;
using PvDotNet;
using PvGUIDotNet;
using System.Drawing;
namespace eBus_Connection
{
public partial class MainForm : Form
{
PvDeviceGEV camera;
PvStreamGEV stream;
PvPipeline pipeline;
PvDisplayThread thread;
bool updating = false;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Shown(object sender, EventArgs e)
{
PvDeviceInfo info;
PvDeviceFinderForm form = new PvDeviceFinderForm();
form.ShowDialog();
info = form.Selected;
camera = PvDeviceGEV.CreateAndConnect(info) as PvDeviceGEV;
stream = PvStreamGEV.CreateAndOpen(info.ConnectionID) as PvStreamGEV;
pipeline = new PvPipeline(stream);
if (camera == null || stream == null)
throw new Exception("Camera or stream could not be created.");
camera.NegotiatePacketSize();
camera.SetStreamDestination(stream.LocalIPAddress, stream.LocalPort);
camera.StreamEnable();
camera.Parameters.ExecuteCommand("AcquisitionStart");
pipeline.Start();
thread = new PvDisplayThread();
thread.OnBufferDisplay += thread_OnBufferDisplay;
thread.Start(pipeline, camera.Parameters);
status.DisplayThread = thread;
status.Stream = stream;
}
void thread_OnBufferDisplay(PvDisplayThread aDisplayThread, PvBuffer aBuffer)
{
Bitmap b = new Bitmap((int)aBuffer.Image.Width, (int)aBuffer.Image.Height);
aBuffer.Image.CopyToBitmap(b);
BeginInvoke(new Action<Bitmap>(ChangeImage), b);
}
void ChangeImage(Bitmap b)
{
if (PictureBox.Image != null)
PictureBox.Dispose();
PictureBox.Image = b;
GC.Collect();//taking this away causes memory to leak rapidly.
}
}
}

It's very likely that somewhere in your code an Image such as a Bitmap is not being disposed. Bitmap extends Image which implements IDisposable which means you need to call Dispose() on it when you're done with it (often by wrapping it with a using statement). You aren't disposing the Bitmap or Image somewhere so the GC finalizes it when it can (or in this case when you explicitly invoke the GC).
Once the GC determines that a class is no longer referenced, it becomes available to clean up... Before cleaning it up, it checks for a finalizer. If a finalizer exists, the class is placed in a special GC finalizer queue that will run the finalizer before cleaning up the resources/memory. Most IDisposable classes have finalizers which allow the GC to do the Dispose() call work in case you forgot to manually dispose the class yourself. It seems that this is what is happening to your code, but without seeing ALL classes I can only guess what isn't disposed (and no idea where).
EDIT: I do have a guess though. I bet the PictureBox.Dispose() call does not dispose PictureBox.Image

If an object implements IDisposable then you should absolutely call Dispose on it but disposing an object doesn't release the memory it occupies. It releases things like, in this case, an image handle. Such resources have to be released first, before memory can be reclaimed, so disposing still helps.
When the GC runs, if an object hasn't been disposed then it must first finalise it, meaning that it must wait longer to reclaim the memory. If the object has been disposed, memory is reclaimed as soon as the GC runs.
The GC runs in the background though. If your application is busy allocating more and more memory then the GC never gets a chance to run and reclaim it, regardless of whether you dispose objects or not. In such cases, you need to invoke the GC explicitly from time to time. Creating multiple images is the most common scenario that requires explicit GC invocation.
It's worth noting that ALL objects remain in memory until the GC runs and cleans them up, whether the object implements IDisposable or not. You normally don't notice it though, because most apps have enough down-time to allow the GC to run implicitly and reclaim that memory. There's nothing special about your Bitmap objects in this regard.

You are disposing the picture box instead of the image. Even if that will dispose the image in the picture box, it will only do that the first time. After that the picture box is in a disposed state and calling Dispose again will do nothing.
You should get the image reference from the picture box and dispose it once it's not used any more:
void ChangeImage(Bitmap b) {
Image oldImage = PictureBox.Image;
PictureBox.Image = b;
if (oldImage != null) {
oldImage.Dispose();
}
}
A bitmap that isn't disposed correctly have to be finalized before it can be collected. There is a background thread that finalizes objects that needs to be collected, but if you abandon objects faster than that thread can take care of them, you will run out of memory.
When the bitmap is disposed correctly, it becomes a regular managed object that can be collected right away whenever the garbage collector wants to.

Related

How do I properly dispose and free the memory used for V8.Net.V8Engine instances?

I'm running into an issue when using my V8Engine instance, it appears to have a small memory leak, and disposing of it, as well as forcing the garbage collection doesn't seem to help much. It will eventually throw an AccessViolationException on V8Enging local_m_negine = new V8Engine() claiming a Fatal error in heap setup, Allocation failed - process out of memory and Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Monitoring the program's memory usage through Task manager whilst running confirms that it is leaking memory, around 1000 KB every couple of seconds I think. I suspect it is the variables being declared within the executed script not being collected, or something to do with the GlobalObject.SetProperty method. Calling V8Engine.ForceV8GarbageCollection(), V8Engine.Dispose() and even GC.WaitForPendingFinalizers() & GC.Collect() doesn't prevent this memory being leaked (Although it is worth noting that it seems to leak it slower with these commands in place, and I know I shouldn't use GC but it was there as a last resort to see if it would fix the issue.)
A tangential issue that could also provide a solution is the inability to clear the execution context for V8Engine. I am required to dispose and re-instantiate the engine for each script, which I believe is where the memory leak is happening, otherwise I run into issues where variables have already been declared, causing V8Engine.Execute() to throw an exception saying such.
I can definitely confirm that the memory leak is something to do with the V8Engine Implementation, as running the older version of this program that uses Microsoft.JScript has no such memory leak, and the memory used remains consistent.
The affected code is as follows;
//Create the V8Engine and dispose when done
using (V8Engine local_m_engine = new V8Engine())
{
//Set the Lookup instance as a global object so that the JS code in the V8.Net wrapper can access it
local_m_engine.GlobalObject.SetProperty("Lookup", m_lookup, null, true, ScriptMemberSecurity.ReadOnly);
//Execute the script
result = local_m_engine.Execute(script);
//Please just clear everything I can't cope.
local_m_engine.ForceV8GarbageCollection();
local_m_engine.GlobalObject.Dispose();
}
EDIT:
Not sure how useful this will be but I've been running some memory profiling tools on it and have learnt that after running an isolated version of the original code, My software ends up with a large amount of instances of IndexedObjectList's full of null values (see here: http://imgur.com/a/bll5K). It appears to have one instance of each class for each V8Engine instance that is made, but they aren't being disposed or freed. I cant help but feel like I'm missing a command or something here.
The code I'm using to test and recreate the memory leak that the above implementation causes is as follows:
using System;
using V8.Net;
namespace V8DotNetMemoryTest
{
class Program
{
static void Main(string[] args)
{
string script = #" var math1 = 5;
var math2 = 10;
result = 5 + 10;";
Handle result;
int i = 0;
V8Engine local_m_engine;
while (true)
{
//Create the V8Engine and dispose when done
local_m_engine = new V8Engine();
//Set the Lookup instance as a global object so that the JS code in the V8.Net wrapper can access it
//local_m_engine.GlobalObject.SetProperty("Lookup", m_lookup, null, true, ScriptMemberSecurity.ReadOnly);
//Execute the script
result = local_m_engine.Execute(script);
Console.WriteLine(i++);
result.ReleaseManagedObject();
result.Dispose();
local_m_engine.Dispose();
GC.WaitForPendingFinalizers();
GC.Collect();
local_m_engine = null;
}
}
}
}
Sorry, I had no idea this question existed. Make sure to use the v8.net tag.
Your problem is this line:
result = local_m_engine.Execute(script);
The result returned is never disposed. ;) You are responsible for returned handles. Those handles are struct values, not class objects.
You could also do using (result = local_m_engine.Execute(script)) { ... }
There is a new version released. I am finally resurrecting this project again as I will need it for the FlowScript VPL project - and it now supports .Net Standard as well for cross-platform support!

Why is my windows form falling back to the Dispose method when it hasn't been instructed to?

I have a windows forms application that opens a dialog box to accept a preference setting.
The code to open the dialog box is as follows:
private void HandleOutputBufferSetting(object sender, EventArgs e)
{
if (this.BufferEditor.Visible)
return;
else
if (this.InvokeRequired)
this.Invoke(new Action(delegate { this.HandleOutputBufferSetting(sender, e); }));
else
{
this.ShowBufferSizeEditor();
return;
}
}
protected void ShowBufferSizeEditor()
{
if (this.BufferEditor == null)
{
this.BufferEditor = new BufferSizeEditor();
this.ShowBufferSizeEditor();
return;
}
else
{
if (this.BufferEditor.Visible)
{
throw new Exception("The Buffer Editor cannot be shown as it is already visible.");
}
else
{
this.BufferEditor.ShowDialog(this);
return;
}
}
}
The execution of all of the above code completes successfully - but upon closing the aforementioned dialog box, the program begins disposal of the dialog boxes parent window; code for which is automatically generated by the Visual Studio designer, and is as follows:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
The stack trace at this point of execution indicates that a segment of external code initialized the Main method I've crafted, followed by an execution of another external method, followed by this disposal.
If anyone has any suggestions as to what might be causing this I am sure I would be appreciative.
The code inside and around the Main method is as follows:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new UndisclosedObjectType());
}
refer Implementing a Dispose Method
A protected virtual (Overridable in Visual Basic) Dispose method whose signature is:
The disposing parameter is a Boolean that indicates whether the method call comes from a Dispose method (its value is true) or from a finalizer (its value is false).
The body of the method consists of two blocks of code:
A block that frees unmanaged resources. This block executes regardless of the value of the disposing parameter.
A conditional block that frees managed resources. This block executes if the value of disposing is true. The managed resources that it frees can include:
Managed objects that implement T:System.IDisposable.
The conditional block can be used to call their Dispose implementation. If you have used a safe handle to wrap your unmanaged resource, you should call the SafeHandle.Dispose(Boolean) implementation here.
Managed objects that consume large amounts of memory or consume scarce resources.
Freeing these objects explicitly in the Dispose method releases them faster than if they were reclaimed non-deterministically by the garbage collector.
If the method call comes from a finalizer (that is, if disposing is false), only the code that frees unmanaged resources executes. Because the order in which the garbage collector destroys managed objects during finalization is not defined, this prevents the finalizer from trying to release managed resources that may have already been reclaimed.
Conclusion
Refer to Form.ShowDialog Method
Because a form displayed as a dialog box is hidden instead of closed,
you must call the Dispose method of the form when the form is no
longer needed by your application.
so even a protected virtual Dispose method is called,
but it only free unmanaged resources of BufferEditor but not the managed resource if disposing is false. To really dispose your dialog box, you need BufferEditor.Dispose();
As far as I can think of, the only reason for the Dialog to be disposed other than manually is either because:
The owner for the owner object that you passed as argument "this" in the ShowDialog() call is no longer existing. A dialog will dispose itself if its owner is disposed.
There are for any reason no references pointing TO the dialog in memory at one point and Carbage Collector disposed the dialog, this may happen because the object from which the reference to the dialog's is kept is destroyed. (The BufferSizeEditor)
I think example 2 is almost impossible, since a reference to the dialog is kept as a child of its owner component. Unless you would be messing with this.
The code
ShowDialog(this);
opens a form as a subcontext of the current running thread. After loosing focus to this form, the windows automatically runs Dispose.
To stop that, you have to change ti to
Show();
and
Hide();

Memory not freeing after Obj.Close()

I'm having an issue with regards on memory management with our system.
Basically here is my design:
Load the List of the Records.
frmBrowse Memory used
90MB
After clicking record, it will pop another form which is the detailed form of the record selected
frmAP
Memory used 110MB
private void ViewRecord()
{
try
{
if(oAP!=null)
oAP = new frmAP();
oAP.LoadRecordDetails();
oAP.Show();
}
catch (Exception ex)
{
clsClass.oGenMethods.ErrorMessage(ex.Message, "frmBrowse", "EditSearchFields");
}
}
When the user CLOSE, i actually Hide it (frmAP )to prevent re-query datas such as lookup tables and others - frmAP - Memory used 110MB
On the frmAP_Close()
this.Hide();
-Memory at 110MB
After hiding the form (frmSomeForm ) the memory remains at 110MB
When the user close the Form(frmBrowse) where "frmAP" was called/instantiate
public void tsClose_Click(object sender, EventArgs e)
{
if (oAP != null)
{
oAP .Dispose();
oAP .Close();
GC.Collect();
}
}
The Problem is the Memory is Still at ~110MB Whether the List(frmBrowse) Form and the Record form(frmAp) was closed.
Please advice
Thanks in Advance
UPDATE:
i Tried to delete .Hide() to isolate the problem, but still the memory keeps growing
Calling Close does not release the memory associated with an object. That's the job of the garbage collector. Close or Dispose simply tells the object to release any unmanaged memory or resources it is using. The object, and everything it's referencing, still stays in memory.
To ensure oAP is collected, set it to null:
oAP.Close();
oAP = null;
However, this is likely the wrong thing to do. The whole point of a garbage collector is to collect memory from unreferenced objects when it's needed. So let it do its job, don't force it to run, you don't need to set oAP to null, and oAP and everything it references will be collected when the GC needs to.

C# garbage collector seems to be closing my StreamWriter too early

I have a logger class thats a singleton. In it's destructor I call Close() which prints the footer for the log and then closes the StreamWriter.
public void Close()
{
WriteLogFileFooter();
_logFile.Flush();
_logFile.Close();
}
The problem is when System.Enviornment.Exit(1) is called from elsewhere in the program (portions that I didn't write myself), the footer is never printed and my logger throws an exception for trying to write to a closed stream. I can only assume the Exit command is causing my StreamWriter to be closed before my Singleton is destructed. I tried to use GC.SupressFinalize() on my StreamWriter but that didn't seem to help.
You are violating one explicit rule for finalizers:
The Finalize method should not reference any other objects.
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.90).aspx
It's entirely possible that the managed object you hold a reference to is collected before your object is collected when the application exits.
UPDATE
If you need to clean up managed resources when the application exits, you could hook up the ProcessExit event of AppDomain rather than rely on non-deterministic behavior of finalizer execution.
.NET Console Application Exit Event
You should make your logger implement IDisposable, and use it in a using block. This means that it will be deterministically disposed, whereas now it is being nondeterministically destructed.
The cause of the error is that your stream will sometimes be closed before the logger, as Exit basically destroys everything (nondeterministically) and quits. You should use a deterministic pattern (IDisposable) to avoid this.
In reality, destructors are rarely useful in C#, for the precise reason that they are non-deterministic. They only are worth using for releasing unmanaged resources.
Also, implementing IDisposable may make it inconvenient to use a singleton. I personally think it's better to create an instance to be used throughout the program and disposed at the end, rather than an explicit singleton.
As others have already clearly stated, you should not attempt to access your _logFile object at all from your logger class' finalizer. You shouldn't access any other objects in a finalizer, because the Garbage Collector might already have wiped them out of existence.
I think you could avoid your problem by a few simple steps:
Get rid of your current finalizer.
Perform a _logFile.Flush after every single write, instead of waiting until the very end of your logger object's lifetime when it might already be too late.
Flushing a log file stream frequently seems legitimate to me because the whole point of having a log is using it to find, and deal with, situations where errors have occurred. If your process is suddenly terminated by an exceptional situation, your log should still be as complete as possible; thus flushing the log stream buffer frequently seems a sensible thing to do.
Make your logger implement IDisposable (this MSDN Magazine article will explain to you how this is done) and close your log file stream from there.
I had the same problems and my solution was as follows:
When creating the FileStream in the constructor of your class used GC.SuppressFinalize immediately. This makes you responsible for cleaning the stream
Close the stream in the Dispose() of the class
public class LogFileEventListener : IDisposable
{
private bool disposed = false;
private FileStream fileStream;
public LogFileEventListener(string path)
{
//Opens a new file stream to log file
this.fileStream = new FileStream(path, FileMode.Append, FileAccess.Write);
GC.SuppressFinalize(this.fileStream);
}
/// <summary>Finalize the listener</summary>
~LogFileEventListener() { this.Dispose(); }
/// <summary>Disposes the listener</summary>
public override void Dispose()
{
try
{
if (!this.disposed)
{
/* Do you stuff */
//Close the log file
if (this.fileStream != null)
{
this.fileStream.Close();
this.fileStream = null;
}
base.Dispose();
}
}
finally
{
this.disposed = true;
GC.SuppressFinalize(this);
}
}
}
Most likely the StreamWriter is being closed else where.
Try creating an additional StreamWriter in your singleton's constructor, write to it a few times (to confirm that it is working), then write to it again in the destructor before calling close (close will also flush).
If the above works then you will know some other code is closing your log. If it does not work then you will know that it is a .NET thing (possibly having something to do with how/where the variable is referenced).
According to the documentation, you should be able to work around the issue by putting the StreamWriter in a base class. This of course will not work for you because your test case is not a standard finalization, but is a program exit, meaning .NET does what it wants when it wants. Instead, you should catch the exit event, dispose of this class, then return, to guarantee that things are disposed in the correct order. You should also check if the StreamWriter is already closed in the finalizer in case the program aborts due to an error.

Problem disposing of socket / finalising twice?

I'm working with some code (not mine I hasten to add, I don't trust this much at all) for a class which opens a socket, makes requests and listens for responses, which is throwing an exception in a way I can't comprehend when tested in xunit. I assume the same exception happens "live" but the class is referenced by a singleton so it is probably just hidden.
The problem manifests as "System.CannotUnloadAppDomainException: Error while unloading appdomain" in xunit and the inner exception is "System.ObjectDisposedException" thrown (essentially) inside the finaliser when closing the socket! There are no other reference to the socket which call close and dispose is protected on the Socket class so I'm not clear how else the object could be disposed.
Further, if I merely catch and absorb the ObjectDisposedException xunit terminates when it hits the line to close the listener thread.
I just don't get how the Socket can be disposed before it's asked to close.
My knowledge of sockets is only what I've learnt since finding this problem, so I don't know if I've provided everything SO might need. LMK if not!
public class Foo
{
private Socket sock = null;
private Thread tListenerThread = null
private bool bInitialised;
private Object InitLock = null;
private Object DeInitLock = null;
public Foo()
{
bInitialised = false;
InitLock = new Object();
DeInitLock = new Object();
}
public bool initialise()
{
if (null == InitLock)
return false;
lock (InitLock)
{
if (bInitialised)
return false;
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 8);
sock.Bind( /*localIpEndPoint*/);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(mcIP));
tListenerThread = new Thread(new ThreadStart(listener));
tListenerThread.Start();
bInitialised = true;
return true;
}
}
~Foo()
{
if (bInitialised)
deInitialise();
}
private void deInitialise()
{
if (null == DeInitLock)
return;
lock (DeInitLock)
{
if (bInitialised)
{
sock.Shutdown(SocketShutdown.Both); //throws System.ObjectDisposedException
sock.Close();
tListenerThread.Abort(); //terminates xunit test!
tListenerThread = null;
sock = null;
bInitialised = false;
}
}
}
}
If this object is eligible for garbage collection and there are no other references to the Socket, then the socket's finalizer may well run before your object's finalizer. I suspect that's what's happened here.
It's generally a bad idea (IMO) to do this much work in a finalizer. I can't remember the last time I implemented a finalizer at all - if you implement IDisposable, you should be fine unless you have direct references to unmanaged resources, which are almost always in the form of IntPtrs. Orderly shutdown should be the norm - a finalizer should only usually run if either the program is shutting down, or someone has forgotten to dispose of the instance to start with.
(I know you clarified at the start that this isn't your code - I just thought I'd explain why it's problematic. Apologies if you already knew some/all of this.)
Because of the way the garbage collector and finalizers work, finalizers must only be used if your class is the direct owner of an unmanaged resource such as a Window Handle, a GDI object, a global handle or any other kind of IntPtr.
A finalizer must not try to dispose or even use a managed resource or you will risk calling a finalized or disposed object.
I highly recommend you to read this very important Microsoft article for more detail on how garbage collection works. Also, this is the MSDN reference on Implementing Finalize and Dispose to Clean Up Unmanaged Resources, look carefully for the recommendations at the bottom.
In a nutshell:
If your object is holding an unmanaged resource, you should implement IDisposable and you must implement Finalizer.
If your object is holding an IDiposable object, it should also implements IDisposable on it's own and dispose that object explicitly.
If your object is holding both an unmanaged and a disposable, the finalizer must call two diferent version of Dispose, one that release disposable and unmanaged, the other only unmanaged. This is usually done using a Dispose(bool) function called by Dipose() and Finalizer().
The Finalizer must never use any other resource than the unmanaged resource being released and self. Failing to do so will risk referencing collected or disposed objects, since an object is temporarily ressurected prior to finalization.
New info: this looks like I'm having two problems actually, but the thread one appears to be rather toxic.
From the MSDN link above:
"ThreadAbortException is a special
exception that can be caught, but it
will automatically be raised again at
the end of the catch block."
Some very interesting community content also at that link including "Thread.Abort is a Sign of a Poorly Designed Program".
So at least I have some ammo to get this changed now :)

Categories