简体   繁体   中英

How can I free up MemoryStream in C#?

I'm a bit of a noob with C#. I've tried to do the right thing in terms of managing memory, but I am now getting "out of memory" errors.

UPDATE #2 5 DEC

I solved it, (sort of) I don't understand why, but when I just run the code from my test app with hard-coded parameters, it worked fine, but when I use a dialog (based on OokiDialog) to get some parameters. that's when the memory doesn't get free up.

So, there's something about the dialog that seems to make it want to hold onto these objects, even though they have nothing to do with the dialog itself.

In the end, I was able to "fix" the problem by running the code in it's own task:

Task taskA = Task.Run(() => MakeFiles(path, name));
taskA.Wait();

It gets me working again, but still, I'd LOVE some theories on WHY this is so?

UPDATE 5 DEC

After continued struggles, I decided to copy the relevant code to a test project where I could experiment. After copying, I ran it, and was stunned to see that the memory went up and then DOWN on each iteration. No more "out of memory"!

Still trying to figure out how/why.

UPDATE 4 DEC

I've ruled out the GIF encoder. I commented out that part of the code and the memory still went up and up.

I'm doing quite a bit of loading images and copying their pixels to byte[] arrays. I've been pretty careful to use local variables for the most part, so they shouldn't be persisting.

Is there any way to tell what object or at least class of object is creating those "StreamAsIStream [Strong Handle]" references? ORIGINAL QUESTION

I've done some profiling of the heap and can see that the main culprit is MemoryStreams.

I use MemoryStream in a couple of places, but have been careful to always use "using":

using (MemoryStream mem = new MemoryStream())
{
    ...
}

I noticed that most of the streams on the heap end up showing as:

StreamAsIStream [Strong Handle]

That "strong handle" seems like a clue, perhaps? Ie because it's a strong handle the GC won't clean it up?

I've tried explicitly disposing the streams and then forcing garbage collections, but no matter what I do, they just seem to stick around and eventually I get memory errors.

Could it be something else is internally using a MemoryStream and I'm looking in the wrong place?

Any thoughts or other things I can look at?

You can call stream.Close(); to free up the memory used by the object. The using statement should handle it for you, but I have seen the occasional instance where garbage collection doesn't recognize that the object is no longer in use, especially if you happen to be using WPF.

You could also try implementing the IDisposable interface and then force disposal of objects as well as force garbage collection. I've linked Microsoft doc for that process here .

Here is a more detailed description of Dispose() vs Close() as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM