C# MonoTouch:在自定义图形上下文上绘制PDF时内存泄漏

C# MonoTouch:在自定义图形上下文上绘制PDF时内存泄漏,c#,pdf,xamarin.ios,C#,Pdf,Xamarin.ios,我有一个应用程序,基本上是一个花哨的PDF阅读器。我从互联网上下载了一个PDF,并生成了该PDF的缩略图。然而,当我生成这些缩略图时,似乎分配了大量内存(使用仪器检查),有时GC会收集其中的一部分,但最终,我的应用程序放弃了。在为单个PDF生成缩略图时,我的内存使用量高达38Mb(100x100个缩略图,约60页) 我一次生成一个缩略图,存储它,然后重复这个过程,所以在任何情况下,内存中都应该只有一个缩略图(至少在生成它们的时候)。我生成缩略图的代码如下所示: public UIImage Ge

我有一个应用程序,基本上是一个花哨的PDF阅读器。我从互联网上下载了一个PDF,并生成了该PDF的缩略图。然而,当我生成这些缩略图时,似乎分配了大量内存(使用仪器检查),有时GC会收集其中的一部分,但最终,我的应用程序放弃了。在为单个PDF生成缩略图时,我的内存使用量高达38Mb(100x100个缩略图,约60页)

我一次生成一个缩略图,存储它,然后重复这个过程,所以在任何情况下,内存中都应该只有一个缩略图(至少在生成它们的时候)。我生成缩略图的代码如下所示:

public UIImage GetPageThumbnail(int pageNumber, SizeF size)
{
    //If using retina display, make sure to scale-up the thumbnail as well.
    size.Width = size.Width * UIScreen.MainScreen.Scale;
    size.Height = size.Height * UIScreen.MainScreen.Scale;

    UIGraphics.BeginImageContext(size);
    CGContext tempContext = UIGraphics.GetCurrentContext();
    CGPDFPage page = Document.GetPage(pageNumber);

    RectangleF drawArea = new RectangleF(new PointF(0f, 0f), size);
    CGAffineTransform transform = page.GetDrawingTransform( CGPDFBox.Crop, drawArea, 180, true); //fit PDF to context
    transform.xx = -transform.xx;   // }
    transform.x0 = 0;               // }flip horizontally

    //Console.WriteLine("XX: " + transform.xx + ", YX:" + transform.yx + ", XY:" + transform.xy + ", YY:" + transform.yy + ", X0:" + transform.x0 + ", Y0:" + transform.y0);

    tempContext.ConcatCTM(transform);

    tempContext.DrawPDFPage (page);
    UIImage returnImage = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return returnImage;
}
我已经尝试过显式地处理上下文和PDF页面,但没有任何效果(实际上它看起来更糟,但有一点点盐)


我看过一些关于MonoTouch和PDF(基本上)内存泄漏的帖子,但这已经很老了。我正在使用最新的MonoTouch(5.0.2)。

不确定代码中的问题在哪里,但下面是我生成PDF页面拇指的代码。它工作得完美无缺。也许对你有帮助。我想你的问题可能是当你不在的时候,你对返回的图像做了什么

public static UIImageView GetLowResPagePreview (CGPDFPage oPdfPage, RectangleF oTargetRect)
        {
            RectangleF oOriginalPdfPageRect = oPdfPage.GetBoxRect (CGPDFBox.Media);
            RectangleF oPdfPageRect = PdfViewerHelpers.RotateRectangle( oPdfPage.GetBoxRect (CGPDFBox.Media), oPdfPage.RotationAngle);

            // Create a low res image representation of the PDF page to display before the TiledPDFView
            // renders its content.
            int iWidth = Convert.ToInt32 ( oPdfPageRect.Size.Width );
            int iHeight = Convert.ToInt32 ( oPdfPageRect.Size.Height );
            CGColorSpace oColorSpace = CGColorSpace.CreateDeviceRGB();
            CGBitmapContext oContext = new CGBitmapContext(null, iWidth, iHeight, 8, iWidth * 4, oColorSpace, CGImageAlphaInfo.PremultipliedLast);

            // First fill the background with white.
            oContext.SetFillColor (1.0f, 1.0f, 1.0f, 1.0f);
            oContext.FillRect (oOriginalPdfPageRect);
            // Scale the context so that the PDF page is rendered 
            // at the correct size for the zoom level.
            oContext.ConcatCTM ( oPdfPage.GetDrawingTransform ( CGPDFBox.Media, oPdfPageRect, 0, true ) );
            oContext.DrawPDFPage (oPdfPage);
            CGImage oImage = oContext.ToImage();
            UIImage oBackgroundImage = UIImage.FromImage( oImage );
            oContext.Dispose();
            oImage.Dispose ();
            oColorSpace.Dispose ();

            UIImageView oBackgroundImageView = new UIImageView (oBackgroundImage);
            oBackgroundImageView.Frame = new RectangleF (new PointF (0, 0), oPdfPageRect.Size);
            oBackgroundImageView.ContentMode = UIViewContentMode.ScaleToFill;
            oBackgroundImageView.UserInteractionEnabled = false;
            oBackgroundImageView.AutoresizingMask = UIViewAutoresizing.None;
            return oBackgroundImageView;
        }

1) 您可能希望在tempContext上调用Dispose,因此它在下一次GC之前不会保存在内存中2)您如何处理返回的图像?如前所述,我尝试了disposing和not Disposition@RolfBjarneKvinge我只是将其存储到一个文件中,然后它超出范围,GC应该接管(我在一个循环中为所有图像执行此操作,重用变量)。手动调用GC根本没有什么作用。Arne:在将图像存储到文件后,您会处理它吗?使用CGBitmapContext修复了内存问题,还可以在主线程之外执行该过程,这是一个相当大的好处。我在计算CGImageAlphaInfo时遇到了一些问题,出于某种原因,我得到了一些“无效句柄”异常,但在重新编译几次后,它似乎自行修复了(或者我做了些什么,谁知道呢)。谢谢什么是PdfViewerHelpers?那是你的定制课程吗?是的。很抱歉我没能把它去掉。它通过相应地交换坐标将矩形旋转90度、180度或270度。你能编辑你的帖子并添加这种方法吗?只是为了完整。