[.net] Fun with Pointers (Renamed)

Started by
11 comments, last by Niksan2 16 years, 9 months ago
I've changed the name of the tread to reflect the new direction and issue dealing with proper pointer use. I jumped the gun a little on where to place blame for my little bug. **************************************** Ok so I've had a little pet project I've been working on to learn C# and I've got it coming along. I was fairly happy with where I was with it and I thought I'd see if there were any major problems with memory leaks. The performance tab on the task manager may not be the best way of doing things but it was handy. I noticed I was loosing about 0.5MB when I would do certain things and while not major it was there chipping away at my RAM. It is more than enough to cause problems for someone. So I dug around and found the one line of code causing it which was something to the effect of Bitmap newBitmap = new Bitmap(arguments); This is fairly discouraging seeing that the application does this a lot and that I had nothing to do with the creation of it. More over that it is basically the standard way of creating a new Bitmap. Then there is the issue that when the application is finished that it will be creating even more bitmaps. I tried newBitmap.Dispose(); but that didn't have any effect. So what is people's take on this? Is it some form of Caching, a byproduct of something I should know about, or most importantly, something that can be worked around? [Edited by - Goober King on July 9, 2007 7:33:32 PM]
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
Advertisement
As long as you don't keep any references to it, it'll be freed by the GC sooner or later. I have an app which allocates 200000+ bitmaps of 4mb each. The RAM usage was never over 100mb.. Instead, once it reached some limit, it dropped straight down to 30mb or so.
Quote:Original post by DvDmanDT
As long as you don't keep any references to it, it'll be freed by the GC sooner or later. I have an app which allocates 200000+ bitmaps of 4mb each. The RAM usage was never over 100mb.. Instead, once it reached some limit, it dropped straight down to 30mb or so.


So you think it could be all fine, just need to run the meter up a bit more? I'll see if I can hit it a little harder and see what happens. I had tried it for a little while but I didn't see drop. I'll Give it another shot.



edit******
Nope I wasted all my RAM.
edit2****

Something more is going on. It doesn't seem to be the Bitmap thing after all. Which is almost weird, it really looked like it was for awhile! Not sure what exactly the deal is. Guess I will have to beat my head against the wall for a while longer and try to sort it out.

[Edited by - Goober King on July 8, 2007 9:17:30 PM]
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
I had the same problem, you need to do a .Dispose() on the bitmap once you've finished with it.
Quote:Original post by Niksan2
I had the same problem, you need to do a .Dispose() on the bitmap once you've finished with it.


I actually tried that but it didn't fix the issue, but I did fix it(sort of). For anyone curious here was the deal

I was creating an image in memory then converting it to a windows bitmap. I was allocating memory for it passing the pointer to the bitmap creator like this

Bitmap newimage = new Bitmap(width, height, scan_width,                    System.Drawing.Imaging.PixelFormat.Format24bppRgb                    , transferboy);


The original pointer then goes out of scope and I passed the created bitmap onto a picture box. My downfall was that I was hoping that since the original pointer was destroyed and that managed code was using the data that the garbage collector would reclaim it, but tragically that is not the case. So by widening the scope of the pointer I could later manually free the old data and wiped out the leak.

However, this leaves me with a new problem. My understanding is pointers have a tendency to get moved and start pointing to the wrong place, and that the solution "pinning" isn't all that great an idea. I will have to look into it but in the mean time, anyone have any wisdom as far as this floating pointers biz goes?

***update***
After looking into things I'm thinking since I'm using and external Dll to allocate the memory, that the memory won't be located on the CLI heap, and therefore cannot be moved by the GC. If I'm way of here feel free to let me know. Otherwise I will be spending my time in ignorant bliss....until things start crashing.


[Edited by - Goober King on July 9, 2007 7:29:47 PM]
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
Well, if you only said that in your original post ;) is the dll unmanaged ? if so you will need to clean up the stuff yourself, just add a free function in your dll and actually create a bitmap and copy the bits over rather than passing it an IntPtr as reference.
If your .dll is a managed .dll then yes the GC will clean up the memory for you.

theTroll
Quote:Original post by Niksan2
Well, if you only said that in your original post ;) is the dll unmanaged ? if so you will need to clean up the stuff yourself, just add a free function in your dll and actually create a bitmap and copy the bits over rather than passing it an IntPtr as reference.


I totally would have but I thought I ruled it out with creative commenting. When I started, I was worried about this happening but brain farts being what they are and all........and thats the sad part, I knew it might happen and should have seen it coming.

I'm fairly sure the dll is unmanaged. I'm using what I assume is a windows native dll, and a wrapper for it I more or less took from a tutorial.

Anyway, it's fixed now. So thanks for letting me waste your time.
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
Why do you need to use an external DLL to allocate memory when you could use Marshal.AllocHGlobal? Personally, I'd be leery about using an external library to allocate memory unless it was clear what contract I need to fulfill to make sure the memory is properly cleaned up after.

AFAIK, IntPtr's generally point to unmanaged memory. You have to do fancy things to get them to point to managed memory. Trying to make an IntPtr point to managed memory in C# is not easy, because you get the error message "cannot take the address of, get the size of, or declare a pointer to a managed type." So, anytime you use an IntPtr type you should be thinking about managing its allocation and deallocation.

If all you're doing with this memory is putting it into a bitmap and then forgetting about it (or wanting to), then probably what would be better would be to create a blank bitmap with the width,height that you want, then lock it and copy the image data into it. This way you don't have to manage the memory used by the bitmap yourself.
Quote:Original post by kanato
Why do you need to use an external DLL to allocate memory when you could use Marshal.AllocHGlobal? Personally, I'd be leery about using an external library to allocate memory unless it was clear what contract I need to fulfill to make sure the memory is properly cleaned up after.

AFAIK, IntPtr's generally point to unmanaged memory. You have to do fancy things to get them to point to managed memory. Trying to make an IntPtr point to managed memory in C# is not easy, because you get the error message "cannot take the address of, get the size of, or declare a pointer to a managed type." So, anytime you use an IntPtr type you should be thinking about managing its allocation and deallocation.

If all you're doing with this memory is putting it into a bitmap and then forgetting about it (or wanting to), then probably what would be better would be to create a blank bitmap with the width,height that you want, then lock it and copy the image data into it. This way you don't have to manage the memory used by the bitmap yourself.


Probably because I'm new to C# and never came across marshal.AllocHGlobal during my search on the subject. What I'm actually doing is using the FreeImage library then taking what I've been working on and converting it into a bitmap I can link to a picturebox for visual feedback. This only happens in a couple of places so its not hard to keep track of. The solution is currently working well and I don't feel the need to rock the boat, though Its worth looking into for future projects for sure.
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork

This topic is closed to new replies.

Advertisement