ImageView Updates Cause Ram Leak

CarbongripCarbongrip USMember ✭✭
edited November 1 in Xamarin.Mac

Hello I seem to have a ram leak that occurs whenever I update an ImageView frequently. I use this to screen capture a single window and play it in a ImageView. The code works as I intend it to but it causes a ram leak whenever I include remoteWindowFrame.Image = new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height));

Here is the code I use...

Timer frameTimer = new Timer(createSingleWindowShot, null, 0, 1000/60);

private void createSingleWindowShot(Object o)
{
    uint testID = 329;
    // Create an image from the passed in windowID with the single window option selected by the user.
    IntPtr windowImage = CGWindowListCreateImage(CGRect.Null, CGWindowListOption.IncludingWindow, testID, CGWindowImageOption.Default);
    CGImage cgImage = new CGImage(windowImage);
    InvokeOnMainThread(delegate {
        remoteWindowFrame.Image = new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height));
    });
}

Answers

  • ChrisHamonsChrisHamons USXamarin Team Xamurai
    edited November 1

    Being in C# does not prevent you from having to follow the Create rule:

    https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html

    specially when you are calling into CG functions directly.

    You code does this:

    • CGWindowListCreateImage - This is a create function, so you own the memory it returns
    • CGImage (IntPtr) - Since you called this one we are not telling the CGImage to "take ownership".
    • New NSImage (CGImage, CGSize) - We're not taking ownership of this here either, just using it to init

    So you can either:

    • Use new CGImage (windowImage, true) to tell the CGImage it owns the memory you manually allocated
    • Call CFRelease by hand at the end.

    The first is preferred in almost all cases.

  • CarbongripCarbongrip USMember ✭✭

    I can't seem to reference CGImage(IntPtr handle, bool owns) and according to the api it doesn't exist. How do I access it?

    https://developer.xamarin.com/api/type/MonoMac.CoreGraphics.CGImage/

    Im still getting used to mac foundations, I'm used to .Net on Windows WPF.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    My mistake, CGImage (IntPtr, bool) is internal. I forgot to check.

    Try this:

            ObjCRuntime.Runtime.GetINativeObject<CoreGraphics.CGImage> (ptr, true);
    
  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Im still getting used to mac foundations, I'm used to .Net on Windows WPF.

    Expect a bit of a bumpy transition, there is a lot wanting in Cocoa in when compared to some of the nicer bits of WPF (I used to do WPF).

    This post has a number of resources that may be useful: https://forums.xamarin.com/discussion/comment/302822/#Comment_302822

Sign In or Register to comment.