I need help with my code.
Ive been trying to use RedGate to monitor the memory usage of my application, after hours of testing It pointed out the unmanaged code of my application, and I could only think of my webservice calling as the only or somewhat unmanaged part of my code. Ive been debugging for hours and cant seem to find out where or what really happened. below is my code.
private void btnstart_Click(object sender, EventArgs e)
{
btnPressed = !btnPressed //boolean
if(btnPressed)
{
myTask = Task.Factory.StartNew(() =>
{
do {
_checkMatches(token.Token);
} while (token.IsCancellationRequested != true);
},token.Token);
}
else
{
token.Cancel();
try {
Task.WaitAny(myTask);
}
catch(Exception Error) {
//Put to logs
}
finally
{
if(myTask.isCancelled || myTask.IsCompleted || myTask.IsFaulted)
{
myTask.Dispose();
}
}
}
}
private void _checkMatches(CancellationToken token)
{
try
{
if(token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
EndpointAddressBuilder ServiceEndPoint = new EndpointAddressBuilder(//Read Endpoint From Notepad);
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });//just bypassing validation for test purposes
// WebService is an ASMX web service
using (WebService.SoapClient client = new WebService.SoapClient())
{
WebService.checkResponse clientRes = client.checkClient();
if(clientRes.response == 1 || clientRes.response == 2) {
//Put to Logs
}
}
}
catch(Exception error){
//Put to logs
}
}
I cant seem to find any error in this code. Can Someone Help me with what is the problem why my unmanaged code is leaking? or could someone suggest what tools to be used or even suggest to find the leaking part of my code? Any Help would be great.
If you are using RedGate memory profiler it should tell you more than just pointing unmanaged resources. Because you are not directly creating any unamanged resources, most likely your memory leak is caused by a managed object or an event subsciption(or callback subscription).
Standard .net managed objects which have unmanaged resources (ie : WebService.SoapClient) have implemented the finalizer(destructor) in order to get rid of its unmanaged resources in any case if Dispose is not called. If you use a standard .net managed object which has unmanaged resources and don't call the dispose (this is bad), still it will release unamanged resources when it is going through the finalization. Generally this shouldn't cause unmanaged resource memory leak.
How to check if there is any memory leak:
Execute your memory consumption logic a few times. Go to the Instance list and see if there is any instances are growing. Select the 'Objects with Source' option in order to get rid of heaps of system object. You should see more instances that there should be if there is any memory leak.
If there is any growing instances, pick one and see the objects retention graph which will show you exactly which instance holds the reference.
And also, make sure that you have implemented IDisposable properly and dispose all disposable objects and unsubscribe from all event subscriptions.
Have a look at below walkthroughs
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/walkthrough http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/
Related
I'm working with .NET Framework 4.8 and NuGet libraries: OpenCvSharp4, OpenCvSharp4.runtime.win, OpenCvSharp4.Windows and I'm trying to code a simple WebcamStreaming class that takes as input a WPF System.Windows.Controls.Image and exposes some Start and Stop methods to show the camera output.
I did it, and it works, but there are two things I'm not sure about:
CPU gets very high while streaming, around 30/40%. I think it is the VideoCapture read frames loop, so I put an await Task.Delay(10) to free some resources on each cycle and it is working. Now the CPU is always < 10%. But is this the correct solution? Am I doing something wrong earlier?
When I close the application, I get always this exception: Managed Debugging Assistant 'DisconnectedContext' : 'Transition into COM context 0x12f6648 for this RuntimeCallableWrapper failed with the following error: The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED)). This is typically because the COM context 0x12f6648 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else. Releasing the interfaces from the current COM context (COM context 0x12f6700). This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.'.
Do you know what is it and what I'm doing wrong?
The code
You can find the whole example on a GitHub repository I've created.
The interesting part of the frames fetch loop:
_previewTask = Task.Run(async () =>
{
using (var frame = new Mat())
{
while (!_cancellationTokenSource.IsCancellationRequested)
{
_videoCapture.Read(frame);
if (!frame.Empty())
{
_lastFrame = BitmapConverter.ToBitmap(frame);
var lastFrameBitmapImage = _lastFrame.ToBitmapSource();
lastFrameBitmapImage.Freeze();
_imageControlForRendering.Dispatcher.Invoke(() => _imageControlForRendering.Source = lastFrameBitmapImage);
await Task.Delay(10);
}
}
}
}, _cancellationTokenSource.Token);
The disposal process (I call it when the application gets closed):
public void Dispose()
{
_cancellationTokenSource?.Cancel();
if (_videoCapture?.IsDisposed == false)
{
_videoCapture?.Dispose();
_videoCapture = null;
}
_lastFrame?.Dispose();
}
Update for the second point
The problem was caused by the fact that the thread in which I was calling Dispose wasn't the same thread in which I created VideoCapture.
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!
I am working on a .NET program that starts a new instance of Excel, does some work, then ends, but must leave Excel running. Later, when the program runs again, it will attempt to hook into the previous instance.
What is the best way to handle the releasing of COM objects in this situation? If I do not do a "ReleaseComObject" on the app object the first time, then on the second run get the active object, then finally release the com object, do I have a memory leak?
The following simplified code illustrates what I am trying to do:
private Microsoft.Office.Interop.Excel.Application xlsApp;
private Microsoft.Office.Interop.Excel.Workbook xlsWb;
public void RunMeFirst()
{
//Start a new instance
System.Type oSEType = Type.GetTypeFromProgID("Excel.Application");
xlsApp = Activator.CreateInstance(oSEType);
xlsWb = xlsApp.Workbooks.Open("C:\\test1.xls");
//Do some stuff
xlsWb.Close(false);
Cleanup(ref xlsWb);
//Do not quit Excel here
//No Cleanup of xlsApp here? Is this OK?
System.Environment.Exit(0);
}
public void RunMeSecond()
{
//Hook into existing instance
xlsApp = Marshal.GetActiveObject("Excel.Application");
xlsWb = xlsApp.Workbooks.Open("C:\\test2.xls");
//Do some stuff
xlsWb.Close(false);
Cleanup(ref xlsWb);
xlsApp.Quit();
Cleanup(ref xlsApp);
System.Environment.Exit(0);
}
public void Cleanup(ref object theObj)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(theObj);
theObj = null;
}
Thanks
In general, when working with the Office PIAs, i've found that these sorts of problems with objects not being released arise when you have instance variables that hold COM objects. In your case, these would be xlsApp and xlsWb. You don't have to quit the Excel application in order to release the objects, but you do have to perform the following as a cleanup procedure:
Marshal.FinalReleaseComObject(xlsWb);
xlsWb = null;
Marshal.FinalReleaseComObject(xlsApp);
xlsApp = null;
GC.Collect();
Local-scoped variables containing COM objects don't seem to cause this problem, only instance variables. I hope this helps!
I'm a tad confused - at the end of RunMeFirst you exit the process, so is RunMeSecond run in a different process from the first method or the same process?
Either way I would change your code so that xlsWb is scoped locally and just do the following:
public void RunMeFirst()
{
System.Type oSEType = Type.GetTypeFromProgID("Excel.Application");
xlsApp = Activator.CreateInstance(oSEType);
Workbook xlsWb = xlsApp.Workbooks.Open("C:\\test1.xls");
// Do stuff
xlsWb.Close(false);
System.Environment.Exit(0);
}
You shouldn't really call any of the ReleaseComObject methods except in certain circumstances (for example in server applications where many COM objects will all be in use and so it is critical to release objects as soon as possible). The usual mechanism for cleaning up COM object should simply be to let them go out of scope, in which case the COM object will be released using the same magic the GC uses (I believe that it is cleaned up as the finalizer is run, but I'm not 100% sure on this).
The reason why its a good idea to scope xlsWb locally (rather than as a class member or a static member) is that class members will only be cleaned up when the class is cleaned up, and static members are never cleaned up until the appdomain is unloaded. If you do need to clean up a COM object referenced by a static field then the way to do this is to set the static field to null so the underlying COM object can be cleaned up by the GC scoping rules:
xlsWb = null;
Also there should be no real need to call GC.Collect for similar reasons - Mike Rosenblum gives a fair explanation as to why he's calling GC.Collect and ReleaseComObject, but no real justification as to why he isn't just satisfied with letting the garbage collector do its job. Like I said, there are situations where you might want more control over the release of COM objects, however these are the exception not the rule.
You may also find reading Marshal.ReleaseComObject Considered Dangerous useful.
I've got a simple web application using ASP.NET MVC3 and Ninject.Web.MVC (the MVC3 version).
The whole thing is working fine, except when the application ends. Whenever it ends, the kernel is disposed, as seen in Application_End() in NinjectHttpApplication:
Reflector tells me this:
public void Application_End()
{
lock (this)
{
if (kernel != null)
{
kernel.Dispose();
kernel = null;
}
this.OnApplicationStopped();
}
}
What happens is that my webserver goes down with a StackOverflowException (I tried both IIS7 and the built-in webserver in VS2010). I can only assume this is where it's going wrong, as I haven't written any code myself on application end.
I figured out that the Kernel knows how to resolve IKernel (which returns the Kernel itself), might this be something that could cause the stack overflow? I could imagine something like this happens:
Kernel.Dispose()
Dispose all instances in the kernel
hey! look at this, the kernel is also in the kernel. Return to step 1.
In other words, the kernel gets disposed, disposes all references it holds (which includes a self-reference), which causes it to dispose itself.
Does this make any sense?
Edit:
It seems the problem is in NinjectHttpApplication. Take a look at this activation code:
public void Application_Start()
{
lock (this)
{
kernel = this.CreateKernel();
...
kernel.Bind<IResolutionRoot>().ToConstant(kernel).InSingletonScope();
...
}
}
It seems ok, but what's happening now is that whenever an IResolutionRoot is called, kernel is cached within itself. When disposing the kernel, the cache is emptied which disposes all cached objects, which causes a circular reference.
A simple solution for NinjectHttpApplication would be to simply change the binding. Change the constant binding to a method one:
kernel.Bind<IResolutionRoot>().ToConstant(kernel).InSingletonScope();
becomes
kernel.Bind<IResolutionRoot>().ToMethod(x => this.Kernel);
This solves the problem, but I am not sure if the whole circular dispose caching issue is a bug in ninject.
I encountered the same issue.
I ended up copying the code for NinjectHttpApplication and removing Kernel.Dispose() in the Application_End function.
public void Application_End()
{
lock (this)
{
if (kernel != null)
{
//kernel.Dispose();
kernel = null;
}
this.OnApplicationStopped();
}
}
That should fix the error. Not sure if there is a planned fix for it though.
There was a bug in MVC3. It's fixed in the latest revision and will be part of the RC2 comming next week. In the mean time take the build from the build server http://teamcity.codebetter.com
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 :)