I have a collections of objects, each object contains a BitmapImage. I have this collection bound to a FlipView. When user flips a page in he FlipView, the BitmapInmage of the selected object gets loaded from ApplicationData and I set the BitmapImage of the previous object to null to relieve the memory. The problem is, that the memory never gets relieved and the app crashes after some time of flipping. When I look at the collection, only the actual item has its BitmapImage set, all the others have it as null. So how do I relieve the memory?
The way I load the images:
StorageFile s = await ApplicationData.Current.LocalFolder.GetFileAsync(localFilename);
BitmapImage bitmapImage = new BitmapImage();
using (var stream = await s.OpenAsync(FileAccessMode.Read))
{
bitmapImage.SetSource(stream);
}
return bitmapImage;
Edit: I think the problem may be the way I load the Image, I guess the file stream does not get freed
I ran into a similar issue with Windows Phone 7 applications.
One trick that worked for me was removing the image from the parent element.
grid1.Children.Remove(image1);
image1 = null;
I'm not sure if this will help in your situation though.
More details about this issue from my blog post.
What worked for me was setting the UriSource property to null before setting the object itself to null.
If these images are using large amounts of memory then it might make sense to force Garbage Collection to free the memory. This will only work if you've removed all strong references to the memory. You can run into performance problems if you're too aggressive in forcing garbage collection, so you'll want to experiment with this. For example, you might want to force collection only after "nulling out" a few images.
You can force garbage collection using the GC.Collect method.
http://msdn.microsoft.com/en-us/library/bb384155.aspx
If you are using x:Bindings in UWP, you may find a similar issue, however, if you run Bindings.Update() after clearing out your classes (Say your image is in a class, held in an observable collection), first run .Clear() on that ObservableCollection, then Bindings.Update(), then you will find that your will regain free space.
In .net setting something to null never does anything - GC is unrelated and happens when it chooses. Instead, check whether the image implements IDisposable: if it does, you should be calling Dispose() when you have finished with it. Moat commonly, you would do this automatically via a "using" statement:
using(var img = GetImage()) {
// todo: some stuff involving img
}
Related
Using the System.DirectoryServices.Protocols library:
I have a class LdapItemOperator that takes a SearchResultEntry object from an LDAP query (not Active Directory related) and stores the attributes for the object in a field: readonly SearchResultAttributeCollection LdapAttributes.
The problem I am experiencing is that when I have a large operation the garbage collector seems to never delete these objects after they ought to have been disposed because of the LdapAttributes field in my objects, at least I think that's the problem. What ways can I try to dispose of the objects when they are no longer required? I can't seem to find a way to incorporate a using statement in there, although I only have little experience with it.
As an example, let's say I have the following logic:
List<LdapItemOperator> itemList = GetList(ldapFilter);
List<bool> resultList = new List<bool>();
foreach (IdmLdapItemOperator item in itemList) {
bool result = doStuff(item);
resultList.Add(result);
}
//Even though we are out of the loop now, the objects are still stored in memory, how come? Same goes for the previous objects in the loop, they seem to remain in memory
Logic.WriteResultToLog(result);
After a good while of running the logic on large filesets, this process starts taking up enormous amounts of memory, of course...
I think you might be a little confused about how GC works. You can never know exactly when GC will run. And objects you are still holding a reference to will not be collected (unless it's a weak reference...).
Also "disposing" is yet another different concept, that hasn't much to do with GC.
Basically, all objects will be in memory already after the call to GetList. And memory consumption will not change much after that, the foreach loop shouldn't affect it at all.
Without knowing your implementation, maybe try returning an enumerable instead of a single list, or make multiple batched calls.
Background:
I'm building an application which will open a potentially large number of photos, generate a thumbnail to present to the user, then allow things like exif data viewing/clearing and minor post processing.
I want to allow the user to scroll through the images without pausing to load each one as it becomes visible, but I also don't want to keep dozens or hundreds of full size bitmap images in memory.
I had built a prototype of this task using System.Drawing using Image objects and their GenerateThumbnailImage method, but decided to move to WPF and use System.Windows.Media.ImageSource derived objects and the TransformedBitmap with a ScaledTransform to generate the thumbnail.
What I found, though, is that when I create a TransformedBitmap, it has a reference back to the source image, which is available and still present in memory. How do I release this source object?
Some relevant C# code:
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System;
...
private void LoadImage(){
//Called by my class internally to handle generating the thumbnail
//Intent is to keep only metadata and a thumbnail bitmap in memory
Stream handle = File.OpenRead(FileName);
BitmapDecoder source = BitmapDecoder.Create(handle,BitmapCreateOptions.None,BitmapCacheOption.OnLoad);
handle.Dispose();
//Determine a scaling ratio to force the larger of height or width to fit inside my desired thumbnail size (int)MaxDim.
ScaleRatio = Math.Min(MaxDim/Math.Max(source.Frames[0].PixelHeight,source.Frames[0].PixelWidth),1); //a public member of the class, Double
_ImageSource = new TransformedBitmap(source.Frames[0],new ScaleTransform(ScaleRatio,ScaleRatio)); //private member of the class, ImageSource
_ImageSource.Freeze();
_Exif = source.Frames[0].Metadata; //private member of the class, ImageMetadata
}
The problem here is that while I hoped that the (BitmapDecoder)source would be released, I can still access the object via _ImageSource.Source.
I have considered using CopyPixels or encoding the TransformedBitmap back into a byte[] stream to create a new, hopefully unattached bitmap, but both of those methods seem like unnecessary reprocessing if I can just abandon or dispose of the source or if there is some simple and fast way to create a shallow clone that I haven't discovered. My attempt at a shallow clone using BitmapFrame.Create(TransformedBitmap) doesn't free the memory either, but also doesn't leave me with an obvious reference.
Some testing watching memory consumption shows each image loaded costs about 30MB. An approximately 200x200#32bpp image should be about 160kB, not counting overhead.
The question again as a TL;DR: how do I release the reference to the source bitmap after a TransformedBitmap uses it?
I've been all over the documentation and various samples, and all of my code appears to be as it should be.
However, I'm experiencing a memory leak that I cannot seem to plug. Here's what I know:
It happens when calling into an IAsyncOperation method and actually attach a .done or .then to the WinJS.Promise.
Leaking objects appear to include a Windows.Foundation.IAsyncOperation<T>, an AsyncOpPromise (dynamically created when the async method is called for the first time?) and most importantly, the result of the operation (T) which can be a very large object.
I can see the apparent leaks in the JavaScript memory profiler, no matter whether the result is a number, a string, or any other object type.
For example:
//This one leaks
document.getImageSourceAsync().done(function(source) {
//The intention is to do something with the image, but it doesn't really matter what does or does not happen here.
});
//This one doesn't leak
document.getImageSourceAsync();
I've created a sample project here: http://sdrv.ms/12TvPOa
Thank you in advance for any help.
Adam
I am using a 3rd-party object I didn't create that over time consumes a lot of resources. This object shouldn't in any way contain a state, it simply performs a calculation. Despite this fact, everytime I call a specific function of this object a little more memory is consumed. A few hours later, and my program is sitting at gigabytes of allocated memory.
The object was origionaly initialized as a static member of my Program class in my command-line application. I have found that if I wrap my entire program in an class, and reinitialize it every now and again, the older (and bloated) object is unallocated by GC and a new smaller object replaces it.
My issue is this method is quite clumsy and ruins the flow of my Program.
Is there any other way you can dispose of an object? I am lead to believe GC.Collect() will only dispose unreachable code. Is there anyway I can make an object 'unreachable'?
Edit: As requested, the code:
static ILexicon lexicon = new Lexicon();
...
lexicon.LoadDataFromFile(#"lexicon.dat", null);
...
byte similarityScore(string w1, string w2, PartOfSpeech pos, SimilarityMeasure measure)
{
if (w1 == w2)
return 255;
if (pos != PartOfSpeech.Noun && pos != PartOfSpeech.Verb)
return 0;
IList<ILemma> w1_lemmas = lexicon.FindSenses(w1, pos);
IList<ILemma> w2_lemmas = lexicon.FindSenses(w2, pos);
byte result;
byte score = 0;
foreach (ILemma w1_lemma in w1_lemmas)
{
foreach (ILemma w2_lemma in w2_lemmas)
{
result = (byte) (w1_lemma.GetSimilarity(w2_lemma, measure) * 255);
if (result > score)
score = result;
}
}
return score;
}
As similarityScore is called, more memory is allocated to a private member of lexicon. It does not implement IDisposable and there are no obvious functions to clear the memory. The library is based on WordNet, and uses an algorithm to find path lengths in the hypernym tree to calculate the similarity of two words. Unless there is caching, I can't see why it would need to store any memory. What is for sure, is I can't change it. I'm almost certain there is nothing wrong with my code. I just need to dispose of lexicon when it gets too large (N.B. it takes a second or two to load the lexicon from file to memory)
If the object doesn't implement IDisposable and you want to push it out of scope you can set all references to it to null and then the force garbage collection with GC.Collect().
GC.Collect() is very expensive. If you're going to have to do this frequently, you might want to consider contacting the vendor.
Find out:
If you are using their library correctly, or is there something you're doing wrong that's causing the memory leak.
If their library is leaking memory even when used as intended, can they fix the leak?
Additional note: If the 3rd party library is native and you're having to use interop, you can use Marshal.ReleaseComObject to free unmanaged memory.
you could try calling the Dispose() method. This would make the object unusable, so you would have to instantiate another one. I assume your program is in a loop, so it can be a loop variable with the call to dispose at the bottom.
I would suggest that if you can get your hands on a memory profiler, you use it. A memory profiler will let you pause your program, click on a class, and and see a list of objects of that class. One can then click on an object and see how it was created, and the "path" to that object from a root (e.g. there's a static class foo, which holds a reference to a bar, which holds a reference to a boz, which holds a reference to a reallybigthing). Often, seeing that will make it clear what needs to be done to break the chain.
you might be able to download the source from wordnet repository and modify the code since it is an opensource.
I have some code that does
MemoryStream ms = new MemoryStream();
...
return Image.FromStream(ms);
It fails in very eclectic ways since the Image object does not hold a ref to the stream, so it can get disposed if the GC kicks in which results in GDI+ errors.
How do I work around this (without saving the stream to disk, or altering my method sigs) ?
This seems highly unlikely to me - it would cause a problem for almost any use of Image.FromStream.
It seems more likely to me that something's disposing of your MemoryStream, which it shouldn't.
Could you provide a short but complete program which demonstrates the problem? Forcing garbage collection should make it relatively easy to reproduce - you could even create your own class deriving from MemoryStream with a finalizer to show whether or not it really is being collected (well, finalized at least).
There isn't a way to do it without changing your code somewhat. The Remarks section for the documentation for the static FromStream method on the Image class states:
You must keep the stream open for the
lifetime of the Image.
That being said, you have to make sure that while the Image is accessing the Stream, the stream is open. It would also appear (looking through Reflector) that the FromImage method doesn't actually cause the Image instance to hold onto a reference to the Stream the image was loaded from.
That being said, you to somehow link the image and the MemoryStream (or Stream) together so that it doesn't get GCed. If don't really retain "ownership" of the image (it is passed around), then I recommend that you create a data structure which will hold the reference to the Image and to the Stream and pass the two around in tandem.