Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 内存使用和操作图像_C#_Heap Memory_Tobase64string - Fatal编程技术网

C# 内存使用和操作图像

C# 内存使用和操作图像,c#,heap-memory,tobase64string,C#,Heap Memory,Tobase64string,TL;博士转换为base64string的图像在大型对象堆中具有巨大的RAM占用空间 我在windows服务中有一些代码,这些代码使用用户上传的产品图片,将它们标准化为web级格式(他们将上传10MB位图),并执行其他一些操作,如将它们调整为正方形和添加空白填充 然后,它将它们转换为base64字符串,通过rest将它们上传到我们的托管环境中。环境要求这样做,我不能使用URL。当我这样做时,它们被存储在大型对象堆中,程序的RAM使用率随着时间的推移而急剧上升 我如何回避这个问题 这是密码 pri

TL;博士转换为base64string的图像在大型对象堆中具有巨大的RAM占用空间

我在windows服务中有一些代码,这些代码使用用户上传的产品图片,将它们标准化为web级格式(他们将上传10MB位图),并执行其他一些操作,如将它们调整为正方形和添加空白填充

然后,它将它们转换为base64字符串,通过rest将它们上传到我们的托管环境中。环境要求这样做,我不能使用URL。当我这样做时,它们被存储在大型对象堆中,程序的RAM使用率随着时间的推移而急剧上升

我如何回避这个问题

这是密码

private void HandleDocuments(IBaseProduct netforumProduct, MagentoClient client, bool isChild)
{
    if (netforumProduct.Documents == null) { return; }

    for (int idx = 0; idx < netforumProduct.Documents.Count; idx++)
    {
        JToken document = netforumProduct.Documents[idx]["Document"];
        if (document == null) { continue; }

        string fileName = document["URL"].ToString();

        // Skip photos on child products (the only identifier is part of the url string)
        if (fileName.ToLower().Contains("photo") && isChild) { continue; }

        using (HttpClient instance = new HttpClient {BaseAddress = client.NetforumFilesBaseAddress})
        {
            string trimStart = fileName.TrimStart('.');

            string base64String;

            using (Stream originalImageStream = instance.GetStreamAsync("iweb" + trimStart).Result)
            {
                using (MemoryStream newMemoryStream = new MemoryStream())
                {
                    using (Image img = Image.FromStream(originalImageStream))
                    {
                        using (Image retImg = Utility.Framework.ImageToFixedSize(img, 1200, 1200))
                        {
                            retImg.Save(newMemoryStream, ImageFormat.Jpeg);
                        }
                    }

                    newMemoryStream.Position = 0;

                    byte[] bytes = newMemoryStream.ToArray();
                    base64String = Convert.ToBase64String(bytes);
                }
            }

            // MediaGalleryEntry is a simple class with a few string properties
            MediaGalleryEntry mge = new MediaGalleryEntry
            {
                label = "Product_" + netforumProduct.Code + "_image_" + idx,
                content = new MediaGalleryContent
                {
                    base64_encoded_data = base64String,
                    name = "Gallery_Image_" + idx
                },
                file = trimStart
            };

            this.media_gallery_entries.Add(mge);
        }
    }
}
private void handled文档(IBaseProduct netforumProduct、MagentoClient客户端、bool isChild)
{
如果(netforumProduct.Documents==null){return;}
for(int idx=0;idx
这不是最好的代码,可能不是高度优化的,但这是我能做到的最好的

TL;博士转换为base64string的图像在大型对象堆中具有巨大的RAM占用空间

是的,这显然是真的。所有的图像都是巨大的。压缩方法仅适用于存储和传输。但是,当图像加载到内存中(用于显示或进一步处理)时,所有压缩步骤都必须撤消。这是与他们一起工作的人的一个常见陷阱

然后,它将它们转换为Base64字符串,通过rest将它们上传到我们的托管环境中。环境要求这样做,我不能使用URL。当我这样做时,它们会存储在大型对象堆中,并且随着时间的推移,程序的RAM使用率会急剧上升。” Base64无效,但不会增加太多。IIRC增加25%

如果您真的看到这里有问题,或者只是误读了内存占用,那么最大的问题是@CodeCaster发现您保留了一个引用(这是一个真正的问题,也是在.NET中获取内存泄漏的少数方法之一),但即使您丢失了这些,该字符串仍将在内存中保留一段时间

.NET使用GarbageCollection内存管理方法。这种方法有一个问题:当GC收集时,访问同一托管区域的所有其他线程都必须暂停。因此,由于没有更好的术语,GC在运行时非常懒惰。如果它只在应用程序关闭时运行一次,这是理想的情况。唯一的问题是可以使其提前运行的有:

  • 调用
    GC.Collect();
    ,通常不应在生产代码中使用,只有在发生引用内存泄漏时才用于调试
  • 期待的危险
  • 一些可选的GC模式,特别是服务器模式

我只能告诉你,它最终会运行。但我认为你不必知道确切的时间。

一个10 MB的位图可能会变成1 MB的JPEG,而JPEG又会变成1.3 MB的base64字符串。在
this.media\u gallery\u entries.Add(mge)
您保留了对该字符串的引用,因此无法对其进行垃圾收集。这是您的问题吗?是的,这正是问题所在。我真的不确定在发布到web服务后如何处理该字符串。@CarComp停止引用该字符串,GC最终将对其进行收集。无需进行特殊处理,因为这只是一个问题根据您构造web请求的方式,构建文件(即,通过流式传输到该文件,而不是通过构造字符串然后写入该文件)并将其上载可能会避免这种情况(甚至绕过文件并直接流式传输到URL,但这可能更复杂,具体取决于API)。这意味着不使用
Convert
,而是使用支持流的东西。您可以指提供(或生成)的编程API调用REST API可以使用字符串,但这可能并不意味着不可能编写一个没有此缺陷的新API。REST的全部功能是简单明了的,因此任何语言都可以使用该API。最终,它都会通过TCP,s,以字节流的形式结束