System.Drawing Linux 内存使用率高
System.Drawing High memory usage on Linux
有什么方法可以诊断非托管内存泄漏吗?
我正在使用带有 NETCode (barcode) 库的 .NET 5.0 控制台应用程序。它本身的程序很简单,它调用条形码库并从图像创建 base64string 5000 次,我正在使用 'using blocks' 因此处理也正在处理中。
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 上,非托管内存会随着每次迭代不断增加,但根本不会减少(达到 600MB在 5000 次迭代中)。
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
可以找到包含 docker 文件和 dotmemory 快照的整个演示 here。
我能够解决这个问题,并且该解决方案适用于在 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 位彩色图像。
如果明确指定位图使用 24 位:
var bitmap = new Bitmap(_width, _height, PixelFormat.Format24bppRgb);
内存泄漏问题将得到修复。
有什么方法可以诊断非托管内存泄漏吗?
我正在使用带有 NETCode (barcode) 库的 .NET 5.0 控制台应用程序。它本身的程序很简单,它调用条形码库并从图像创建 base64string 5000 次,我正在使用 'using blocks' 因此处理也正在处理中。
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 上,非托管内存会随着每次迭代不断增加,但根本不会减少(达到 600MB在 5000 次迭代中)。
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
可以找到包含 docker 文件和 dotmemory 快照的整个演示 here。
我能够解决这个问题,并且该解决方案适用于在 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 位彩色图像。 如果明确指定位图使用 24 位:
var bitmap = new Bitmap(_width, _height, PixelFormat.Format24bppRgb);
内存泄漏问题将得到修复。