【问题标题】:System.Drawing High memory usage on LinuxSystem.Drawing Linux 上的高内存使用率
【发布时间】:2022-07-19 19:33:29
【问题描述】:

有什么方法可以诊断非托管内存泄漏?

我正在使用带有 NETCode (barcode) 库的 .NET 5.0 控制台应用程序。它本身的程序很简单,它调用条形码库并从图像创建一个 base64 字符串 5000 次,我正在使用“使用块”,因此也正在处理处置。

static void Main(string[] args)
{
    Console.ReadKey();
    for (int i = 0; i < 5000; i++)
    {
        Barcode bar = new Barcode("123456789123456", Type.Code128);
        using (var image = bar.GetImage())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms,ImageFormat.Png);
                var base64 = Convert.ToBase64String(ms.ToArray());
                Console.WriteLine(i);
            }
        }
    }
    Console.ReadKey();
    Console.ReadKey();
}

在 Windows 上,该程序消耗 15-25 MB(不会超过此值),但在 Linux 上,非托管内存会随着每次迭代而不断增加,但根本不会下降(在 5000 次迭代中达到 600MB)。

Linux 点内存:

Windows 点内存:

我在修复 Font, FontFamily 处理问题后尝试了相同的程序,但结果相同。 我面临与 J4LBarcode、BarcodeLib 相同的问题。

我正在使用 docker:

FROM mcr.microsoft.com/dotnet/aspnet:5.0.15-focal as base
FROM mcr.microsoft.com/dotnet/sdk:5.0.406-focal AS build

带有 dockerfile 和 dotmemory 快照的完整演示可以在 here 找到。

【问题讨论】:

  • 我看到new,但我没有看到delete
  • @stark 我不明白?

标签: linux docker memory-leaks .net-5 dotmemory


【解决方案1】:

我能够解决该问题,并且该解决方案适用于在 Linux 上使用 System.Drawing.Bitmap 的任何人。

该问题与 NetBarcode、System.Drawing.Common(至少在 Windows 上)无关。在 linux 环境下,我们使用 libgdiplus。 NetBarcode.Barcode.GetImage() 创建位图:

var bitmap = new Bitmap(_width, _height);

默认情况下,这会创建一个具有 32 位深度 (RGBA) 的位图。

public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32bppArgb)
{
}

我怀疑 Linux GDI+ 无法正确处理 32 位彩色图像。 如果您明确指定位图使用 24Bit:

var bitmap = new Bitmap(_width, _height, PixelFormat.Format24bppRgb);

内存泄漏问题将得到修复。

【讨论】:

    【解决方案2】:

    我将在 Danial Ahmed 的发现中添加一些发现,因为我们遇到了类似的问题,但使用 .NET 6。

    在位图创建中添加PixelFormat.Format24bppRgb 作为参数减少了内存泄漏,但并没有完全消除它。在我们的 dockerfile 中,我们手动添加了旧版本的 GDI (4.2),它消除了内存泄漏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 2013-07-11
      • 2011-09-19
      • 2018-07-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      相关资源
      最近更新 更多