GC contains lots of pinned objects after a while - c#

I have a strange phenomenon while continuously instantiating a com-wrapper and then letting the GC collect it (not forced).
I'm testing this on .net cf on WinCE x86. Monitoring the performance with .net Compact framework remote monitor. Native memory is tracked with Windows CE Remote performance monitor from the platform builder toolkit.
During the first 1000 created instances every counter in perfmon seems ok:
GC heap goes up and down but the average remains the same
Pinned objects is 0
native memory keeps the same average
...
However, after those 1000 (approximately) the Pinned object counter goes up and never goes down in count ever again. The memory usage stays the same however.
I don't know what conclusion to pull from this information... Is this a bug in the counters, is this a bug in my software?
[EDIT]
I do notice that the Pinned objects counter starts to go up as soon the total bytes in use after GC stabilises as does the Objects not moved by compactor counter.
The graphic of the counters http://files.stormenet.be/gc_pinnedobj.jpg
[/EDIT]
Here's the involved code:
private void pButton6_Click(object sender, EventArgs e) {
if (_running) {
_running = false;
return;
}
_loopcount = 0;
_running = true;
Thread d = new Thread(new ThreadStart(LoopRun));
d.Start();
}
private void LoopRun() {
while (_running) {
CreateInstances();
_loopcount++;
RefreshLabel();
}
}
void CreateInstances() {
List<Ppb.Drawing.Image> list = new List<Ppb.Drawing.Image>();
for (int i = 0; i < 10; i++) {
Ppb.Drawing.Image g = resourcesObj.someBitmap;
list.Add(g);
}
}
The Image object contains an AlphaImage:
public sealed class AlphaImage : IDisposable {
IImage _image;
Size _size;
IntPtr _bufferPtr;
public static AlphaImage CreateFromBuffer(byte[] buffer, long size) {
AlphaImage instance = new AlphaImage();
IImage img;
instance._bufferPtr = Marshal.AllocHGlobal((int)size);
Marshal.Copy(buffer, 0, instance._bufferPtr, (int)size);
GetIImagingFactory().CreateImageFromBuffer(instance._bufferPtr, (uint)size, BufferDisposalFlag.BufferDisposalFlagGlobalFree, out img);
instance.SetImage(img);
return instance;
}
void SetImage(IImage image) {
_image = image;
ImageInfo imgInfo;
_image.GetImageInfo(out imgInfo);
_size = new Size((int)imgInfo.Width, (int)imgInfo.Height);
}
~AlphaImage() {
Dispose();
}
#region IDisposable Members
public void Dispose() {
Marshal.FinalReleaseComObject(_image);
}
}

Well, there's a bug in your code in that you're creating a lot of IDisposable instances and never calling Dispose on them. I'd hope that the finalizers would eventually kick in, but they shouldn't really be necessary. In your production code, do you dispose of everything appropriately - and if not, is there some reason why you can't?
If you put some logging in the AlphaImage finalizer (detecting AppDomain unloading and application shutdown and not logging in those cases!) does it show the finalizer being called?
EDIT: One potential problem which probably isn't biting you, but may be worth fixing anyway - if the call to CreateImageFromBuffer fails for whatever reason, you still own the memory created by AllocHGlobal, and that will currently be leaked. I suspect that's not the problem or it would be blowing up more spectacularly, but it's worth thinking about.

I doubt it's a bug in RPM. What we don't have here is any insight into the Ppb.Drawing stuff. The place I see for a potential problem is the GetIImagingFactory call. What does it do? It's probably just a singleton getter, but it's something I'd chase.
I also see an AllochHGlobal, but nowhere do I see that allocation getting freed. For now that's where I'd focus.

Related

AForge, memory stacking up

Im trying to grab a frame with C# and AForge libraries:
...
using AForge.Video
using AForge.Video.DirectShow
namespace Example
{
class Program
{
private static Bitmap mySnap = null;
static void Main(string[] args)
{
snapByte();
}
private static void snapByte()
{
int Counter = 0;
FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(videoNewFrame);
videoSource.Start();
do
{
Thread.Sleep(500);
Counter++;
}
while (mySnap == null && Counter < 4);
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource.WaitForStop();
videoSource = null;
}
MemoryStream myStream = new MemoryStream();
mySnap.Save(myStream, ImageFormat.Png);
byte[] snapByteLength = MyStream.ToArray();
int snapLength = snapByteLength.Length;
Console.WriteLine(snapLength);
Console.ReadLine();
myStream.Dispose();
mySnap = null;
snapByte();
}
}
private static void videoNewFrame(object sender, NewFrameEventArgs eventArgs)
{
mySnap = (Bitmap)eventArgs.Frame.Clone();
}
}
}
this is the exact code im using, i just changed the image byte processing to display the byte length to simplify things..
the problem im having is that the memory will keep staking up anywhere between 1-2 mb each time a snapshot is taken..
i am disposing of all my bitmaps except for the mySnap that im returning to null.. i cant dispose of mySnap because its used again, and i have to declare it global because i use this in snapByte() and newVideoFrame()
but since im reusing mySnap i dont see why would it be stacking up.. it should be overwriting everytime..
i have seen other answers but all have to do with a picturebox, and the answer is to clear the picturebox before loading a new image..
i believe im doing the equivalent here by calling mySnap=null again..
but memory still stacking up...
Thank You..
You are creating an infinite recursion by your unconditional call to snapByte() at the end of the snapByte() method. This creates a loop that will eventually crash once your stack runs out of space; every time your method calls itself, you are setting up a new stack frame that will never be cleared because the method never returns. This may take a while to manifest because of the Thread.Sleep() call that will keep your recursive calls throttled.
Also, any reference that was not nulled before you recursively call snapByte() will be held indefinitely in memory, since those references are alive in a scope that will never exit (because of the infinite recursion) and will never be reclaimed by the GC.
This is the case for your videoDevices collection but more importantly for the snapByteLength array instance, that is holding a copy of the bitmap you just captured. I bet this is the primary cause for your memory leak
Avoiding recursion and converting it to a simple loop should fix your issues.

C# Usercontrol's memory leak

I have some heavy memory leak in my application.
This is the form that loads a lot of stuff in memory, it is a form with 3 FlowLayoutPanel. Every panel has a lot of a UserControl I've created, they're just a picturebox with a label. Let's call the form ColorViewer:
Whenever I open this form it takes close to 300-400 MB of memory and it doesn't seems to release it.
This a graph of the memory usage:
As you can the first time I open ColorViewer it loads everything in memory (close to 400mb) and then it never dispose. After that, every time I open ColorViewer it is disposed correctly.
This is the code I use to load my form, I guess the memory leak is in the loading of the img. As of right now I use the default Dispose():
//Loading of one of the three panel in the form,called 3 time when the form is opened:
colorsViewerPanel.AddColorRange(colours.ConvertAll(x => new ColorBox(x.path_img, x.id,true)));
//Function that loads my UserControl into the panel
public void AddColorRange(List<ColorBox> cBoxList)
{
flowLayoutPanel1.SuspendLayout();
foreach (var cBox in cBoxList)
flowLayoutPanel1.Controls.Add(cBox);
flowLayoutPanel1.ResumeLayout();
}
//This is the ColorBox usercontrol's class
public string pathImg{ get; set; }
public int id{ get; set; }
public bool selected{ get; set; }
//This is the constructor for the UserControl
public ColorBox(string pathImage,int idImage,bool sel = true)
{
InitializeComponent();
pathImg = pathImage;
id = idImage;
selected = sel;
//Load img
if (File.Exists(pathImg))
{
Image img;
using (var bmpTemp = new Bitmap(pathImg))
{
img = new Bitmap(pathImg);
}
panelColor.BackgroundImage = img;
panelColor.BackgroundImageLayout = ImageLayout.Stretch;
labelColor.Text = id;
}
}
Is this normal ?
I think you are not disposing anything useful here:
Image img;
using (var bmpTemp = new Bitmap(pathImg))
{
img = new Bitmap(pathImg);
}
you are just creating an instance (bmpTemp) of the Bitmap class (that is later going to be disposed because of the using statement) and then assigning a new istance of the same class to another variable (img, the one you are effectively using). Anyway, even if you correct this, it will not work for your purposes, because there's no meaning in disposing the Image you are actually showing in a PictureBox (and this will also lead to an exception later on).
As you can read here, it is necessary to call Dispose on an Image object to effectively get rid of its presence in memory, keeping in mind that Bitmap is a wrapper around an unmanaged GDI+ bitmap (and probably requires special needs to get disposed even when wrapped):
Image.Dispose()
That said, given the code you provided and to cut the problem at the root, I guess I would probably implement the IDisposable interface on the ColorBox control to make sure the Dispose method of the Image instance is always called when the control is disposed:
Implement IDisposable correctly
In your specific case, I would consider the Image/Bitmap object as a fully unmanaged object and I would free it in the "free native resources if there are any" section of the Dispose method so that, if someone is using your control without disposing it, the call to the finalizer is going to happen anyway if the object is eligible for finalization. Something like this:
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
// free managed resources
managedResource.Dispose();
}
// free native resources if there are any.
if (!(img is null))
{
// Our Image.
img.Dispose();
}
isDisposed = true;
}

What causes these spikes in freed memory?

This is a chart of available virtual memory, in bytes, for a small application I'm prototyping with. The application runs in a tight loop which adds an integer to the end of a linked list. If there is a certain percentage of virtual memory remaining it goes to the beginning of the loop, otherwise it exits. What is causing the sudden increases in virtual memory at those six places in the graph? My first thought was garbage collection, but since I'm adding new elements to the linked list without deleting any there shouldn't be any unused references to clean up, certainly not in those large amounts. The final jump is over a third of a gigabyte. This is an application compiled for x86 but running on an x64 machine under .NET 4.5. Sorry if this is a duplicate, I don't know what to call the event so it's hard to search for it.
Edit: I can't provide the exact code but this code does demonstrate what I'm seeing.
public void DoIt()
{
ComputerInfo ci = new ComputerInfo();
double memory = 0;
double count = 0;
for (int i = 0; i < 2; i ++)
{
Console.WriteLine(ci.AvailableVirtualMemory);
try
{
while (true)
{
list.AddFirst(892);
count++;
}
}
catch (OutOfMemoryException)
{
memory = ci.AvailableVirtualMemory;
list.Clear();
list = null;
System.GC.Collect();
list = new LinkedList<int>();
Console.WriteLine(memory);
Console.WriteLine(count);
count = 0;
}
}
}

Small Memory Leak

New to threading, delegates, and garbage collection.
I have a C# program in Visual Studio 2013 that runs a loop on background thread to constantly update controls on a form in my main thread. While the loop is running (and only when the loop is running), Performance Monitor shows a small but steady increase in Private Bytes for that program.
When the background thread is stopped and joined, there is no decrease in the Private Bytes usage but it no longer increases. This program needs to run a long time with the looping thread so a small leak could become a problem after hours / days.
I can comment out the lines in the loop where it calls for the update method; this successfully curbs the issue. What am I doing to prevent garbage collection in that method?
P.S.: If you point me to a program for looking through the heap, please give me a step-by-step on how to install and use it. I've been a little burned out lately and what I've seen online so far isn't obvious enough for my brain at the moment.
private IAsyncResult iar; // Store the IAsyncResult to check for completion the next time I call it.
public delegate void Assisted_UpdateTimer(int totalSeconds, int secondsElapsed, int secondsRemaining);
public void UpdateTimer(int totalSeconds, int secondsElapsed, int secondsRemaining)
{
if (this.InvokeRequired || pbTimeBar.InvokeRequired) // If we need to be threadsafe
{
if (iar != null) // If we've invoked something before
{
if (iar.IsCompleted) // If the last thing we invoked has completed
{
this.EndInvoke(iar);
Assisted_UpdateTimer _delegate = new Assisted_UpdateTimer(UpdateTimer);
iar = this.BeginInvoke(_delegate, totalSeconds, secondsElapsed, secondsRemaining);
}
}
else // Invoke for the first time
{
Assisted_UpdateTimer _delegate = new Assisted_UpdateTimer(UpdateTimer);
iar = this.BeginInvoke(_delegate, totalSeconds, secondsElapsed, secondsRemaining);
}
}
else // The actual method code
{
TimeSpan timeElapsed = new TimeSpan(0, 0, secondsElapsed);
TimeSpan timeRemaining = new TimeSpan(0, 0, secondsRemaining);
int percent = (int)(((double)secondsElapsed / (double)totalSeconds) * 100);
if (pbTimeBar.Maximum != totalSeconds) pbTimeBar.Maximum = totalSeconds;
if (secondsElapsed >= 0) pbTimeBar.Value = secondsElapsed; // pbTimeBar is a progress bar
// Add text to progress bar
pbTimeBar.CreateGraphics().DrawString(percent + "%", new Font("Arial", (float)8.25, FontStyle.Regular), new SolidBrush(Color.FromArgb(255, 0, 0, 0)), new PointF(pbTimeBar.Width / 2 - 10, pbTimeBar.Height / 2 - 7));
labElapsed.Text = string.Format("{0:00}:{1:00}:{2:00} Elapsed", timeElapsed.Hours, timeElapsed.Minutes, timeElapsed.Seconds);
labRemaining.Text = string.Format("Remaining {0:00}:{1:00}:{2:00}", timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds);
trayIcon.Text = string.Format("Toast Timer\nRemaining: {0:00}:{1:00}:{2:00}\nElapsed: {3}%", timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds, percent);
}
}
I haven't checked your full code but the memory leak could be a possible output of strong delegate reference. You see, when you attach a delegate to the event of an object, the object will never be garbage collected unless the delegate reference is removed manually. Here is a documentation reference from msdn to help you understand the scenario better and with possible solutions -
http://msdn.microsoft.com/en-us/library/aa970850(v=vs.110).aspx
Listening for events can lead to memory leaks. The typical technique for listening to an event is to use the language-specific syntax that attaches a handler to an event on a source. For example, in C#, that syntax is: source.SomeEvent += new SomeEventHandler(MyEventHandler).
And for the last part of your question - I usually use Ant Profiler for memory testing. It is not free but the trial version usually works and gives you enough time to solve the issue.
http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/
Comment: I am guessing repeating call to UpdateTimer could make a possible memory leak if it is attaching new delegates in each call.

Special case lifetime analysis

Suppose I have
void foo () {
Bar bar = new Bar(); // bar is never referred to after this line
// (1)
doSomethingWithoutBar();
}
At (1), is the object bar is pointing to eligible for garbage collection? Or does bar have to fall out of scope as well? Does it make a difference if GC.Collect is called by doSomethingWithoutBar?
This is relevant to know if Bar has a (C#) destructor or something funky like that.
Objects can become eligible for garbage collection as soon as it's certain that they will no longer be used. It's entirely possible that bar will be garbage collected before the variable goes out of scope.
Proof:
using System;
class Bar
{
~Bar() { Console.WriteLine("Finalized!"); }
}
class Program
{
static void Main(string[] args)
{
Bar bar = new Bar();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
Run in Release Mode (because it doesn't get collected in Debug Mode).
Output:
Finalized!
Press any key to exit...
It also works on ideone which uses Mono. The output is the same.
From a quick reading of the spec, it looks like it's implementation specific. It's allowed to garbage collect it, but not required to.
I get this from a note in section 10.9 "Automatic Memory Management" of the ECMA Spec:
[Note: Implementations might choose to analyze code to determine
which references to an object can be used in the future. For
instance, if a local variable that is in scope is the only existing
reference to an object, but that local variable is never referred to
in any possible continuation of execution from the current execution
point in the procedure, an implementation might (but is not required
to) treat the object as no longer in use. end note]
Emphasis mine.
Without defining what version of the CLR you're referring to, it's impossibledifficult to be definitive about the behaviour that you'll see here.
A hypothetical CLR could, in this example, assuming that the following is true:
The constructor for Bar does nothing
There are no fields that are initialised (i.e. there are no potential side-effects to the objects construction)
Entirely disregard the line Bar bar = new Bar(); and optimise it away as it "does nothing".
As far as my memory serves, in current versions of the CLR bar is eligible for garbage collection the moment after you've constructed it.
Marc answered the question, but here is the solution:
void foo () {
Bar bar = new Bar(); // bar is never referred to after this line
// (1)
doSomethingWithoutBar();
GC.KeepAlive(bar); // At the point where you no longer need it
}
This can definitely occur. For instance, here is a demonstration that an instance can be finalized while you are still executing its constructor:
class Program
{
private static int _lifeState;
private static bool _end;
private sealed class Schrodinger
{
private int _x;
public Schrodinger()
{
//Here I'm using 'this'
_x = 1;
//But now I no longer reference 'this'
_lifeState = 1;
//Keep busy to provide an opportunity for GC to collect me
for (int i=0;i<10000; i++)
{
var garbage = new char[20000];
}
//Did I die before I finished being constructed?
if (Interlocked.CompareExchange(ref _lifeState, 0, 1) == 2)
{
Console.WriteLine("Am I dead or alive?");
_end = true;
}
}
~Schrodinger()
{
_lifeState = 2;
}
}
static void Main(string[] args)
{
//Keep the GC churning away at finalization to demonstrate the case
Task.Factory.StartNew(() =>
{
while (!_end)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
});
//Keep constructing cats until we find the desired case
int catCount = 0;
while (!_end)
{
catCount++;
var cat = new Schrodinger();
while (_lifeState != 2)
{
Thread.Yield();
}
}
Console.WriteLine("{0} cats died in the making of this boundary case", catCount);
Console.ReadKey();
}
}
In order for this to work, you need to emit a Release build and run it outside Visual Studio (as otherwise the debugger inserts code that prevents the effect.) I've tested this with VS 2010 targetting .NET 4.0 x64.
You can tweak the iterations on the 'keep busy' loop to impact the probability of the Cat winding up finalized before its complete construction.

Categories

Resources