Sign in to follow this  

[.net] Fun with Pointers (Renamed)

This topic is 3811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by Niksan2
Ah freeimage, isn't the problem that you weren't calling FreeImage.Unload(FItexture); to free up the resource ?


Nope. Its not actually a Freeimage bitmap. Its a raw bitmap based on a freeimage bitmap. I have to manually allocate a block of memory then Freeimage dumps converted raw data into it that I can use as a standard bitmap. I remember being fairly annoyed at the fact that I had to do it myself seeing as how it was the only function that doesn't allocate on its own.







Share this post


Link to post
Share on other sites
Actually this sort of goes to another post I was doing, IntPtr to IntPtr copying, but I guess depending on what you're doing the following may not help.

There's two ways to get the data from freeimage.

1)

you can use the pointer direct in a bitmap

uint myBitmap = FreeImage.Load();
Bitmap bitmap = new Bitmap((int)FreeImage.GetWidth(myBitmap), (int)FreeImage.GetHeightmyBitmap), (int)FreeImage.GetPitch(myBitmap), PixelFormat.Format32bppArgb, FreeImage.GetBits(myBitmap));

this means you need to have freeimage retain the data while ever you need the bitmap, and call dispose() on the bitmap and FreeImage.Unload() on the freeimage resource when not needed anymore.

2)

is just creating a normal bitmap, getting the BitmapData from it and doing a copy from GetBits() IntPtr to the bitmaps scan0 IntPtr. I use this method but I have an interop helper dll with things like memcpy and some bitmask copying functions as I do a lot of bit manipulation, and runs slow doing all in c# but as I say, I deal with tons of pixels otherwise I wouldn't bother.

But essentially you shouldn't have to take a copy of free images data natively as you have access to the bits already.


hope some of this helps, even though you've already sorted it ;)

Share this post


Link to post
Share on other sites

This topic is 3811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this