使用 GC.AddMemoryPressure() 防止 OutOfMemoryException?

Preventing OutOfMemoryException with GC.AddMemoryPressure()?(使用 GC.AddMemoryPressure() 防止 OutOfMemoryException?)

本文介绍了使用 GC.AddMemoryPressure() 防止 OutOfMemoryException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在调试一种方法,用于在将图像显示在系统中之前用特定文本标记图像.

I'm currently debugging a method we use to tag images with a certain text before displaying them in our system.

标签方法现在是这样的:

The tag method looks like this at the moment:

private static Image TagAsProductImage(Image image)
{
    try
    {
        // Prepares the garbage collector for added memory pressure (500000 bytes is roughly 485 kilobytes).
        // Should solve some OutOfMemoryExceptions.
        GC.AddMemoryPressure(500000);

        using (Graphics graphics = Graphics.FromImage(image))
        {
            // Create font.
            Font drawFont = new Font("Tahoma", image.Width*IMAGE_TAG_SIZE_FACTOR);

            // Create brush.
            SolidBrush drawBrush = new SolidBrush(Color.Black);

            // Create rectangle for drawing.
            RectangleF drawRect = new RectangleF(0, image.Height - drawFont.GetHeight(), image.Width,
                                                    drawFont.GetHeight());

            // Set format of string to be right-aligned.
            StringFormat drawFormat = new StringFormat();
            drawFormat.Alignment = StringAlignment.Far;

            // Draw string to screen.
            graphics.DrawString(TAG_TEXT, drawFont, drawBrush, drawRect, drawFormat);
        }
    }
    // If an out of memory exception is thrown, return the unaltered image.
    catch(OutOfMemoryException)
    {
        GC.RemoveMemoryPressure(500000);
        return image;
    }

    GC.RemoveMemoryPressure(500000);
    return image;
}

将事情放在上下文中:在从我们的图像服务器检索图像并保存到本地缓存(我们的系统与需要相同图片的其他系统共享)之后调用此方法.

To put things in context: This method is being called after an image has been retrieved from our image server and saved to a local cache (that our system shares with other systems that needs the same pictures).

在到达 using (Graphics... 时,我们遇到了 OutOfMemoryExceptions 问题(当需要在标记之前从服务器检索图像时,如果图像存在于缓存中标记没有问题).

We've been having problems with OutOfMemoryExceptions when reaching using (Graphics... (when the image needs to be retrieved from the server prior to tagging, if the image exists in the cache the tagging hasn't been a problem).

为了防止/规避 OutOfMemoryException,我尝试了三种不同的方法,虽然它们有效,但我并不喜欢其中任何一种.

To prevent/circumvent the OutOfMemoryException I've tried three different approaches, and while they work I don't really like any of them.

首先我尝试在调用 Graphics.FromImage(image) 之前做一个通用的 GC.Collect(); (当然)但我不喜欢强迫收集,因为它会对性能造成很大影响.

First I tried doing a generic GC.Collect(); before calling Graphics.FromImage(image) which worked (of course) but I don't like forcing Collects since it leaves a big hit on performance.

我的第二种方法是在 catch 语句中调用 GC.Collect() 然后递归调用 TagAsProductImage(image) 但这可能会导致无限循环如果 GC 未能释放足够的内存.

My second approach was to call GC.Collect() in the catch-statement and then recursively calling TagAsProductImage(image) but this is might lead to a infinite loop if GC fails to free up enough memory.

最后我得到了上面的代码,我不能说我很喜欢.

And finally I ended up with the above code, which I can't say I'm to fond of either.

我可能可以不使用 GC.Collect(),因为从服务获取图像 -> 保存 -> 标记的整个操作是一个相当大的操作,因此从收集将是最小的,但我真的想要一个更好的解决方案.

I can probably get away with using GC.Collect() since the whole operation of getting the image from the service -> saving -> tagging is quite a big one so the performance hit from the collect will be minimal but I'd really like a better solution.

如果有人对此有聪明的解决方案,请分享.

If anyone have a smart solution to this, please share.

推荐答案

如果您正在寻找一种方法来确保您有足够的内存用于操作,请使用 MemoryFailPoint.

这样,通过using,您可以定义一个需要一定内存量的区域.如果不可用,它将抛出可恢复的 InsufficientMemoryException.

With this, through a using, you can define a region in which you will need a certain amount of memory. If that isn't available, it will throw a recoverable InsufficientMemoryException.

请参阅 http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx 了解更多信息.

See http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx for more information.

这篇关于使用 GC.AddMemoryPressure() 防止 OutOfMemoryException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:使用 GC.AddMemoryPressure() 防止 OutOfMemoryException?

基础教程推荐