WOW!!!,看上面356个System.Drawing.Bitmap在等待回收,看起来这是我们的影响因素,我们来查一下代码。
try { cell.Value = string.Empty; Bitmap bitmap; if (url.IsBase64StringValid()) { bitmap = url.Base64StringToBitmap(); } else { bitmap = Extension.GetBitmapByUrl(url); } if (bitmap == null) { cell.Value = ExporterHeaderList[colIndex].ExportImageFieldAttribute.Alt; } else { ExcelPicture pic = CurrentExcelWorksheet.Drawings.AddPicture(Guid.NewGuid().ToString(), bitmap); AddImage((rowIndex + (ExcelExporterSettings.HeaderRowIndex > 1 ? ExcelExporterSettings.HeaderRowIndex : 0)), colIndex - ignoreCount, pic, ExporterHeaderList[colIndex].ExportImageFieldAttribute.YOffset, ExporterHeaderList[colIndex].ExportImageFieldAttribute.XOffset); CurrentExcelWorksheet.Row(rowIndex + 1).Height = ExporterHeaderList[colIndex].ExportImageFieldAttribute.Height; pic.SetSize(ExporterHeaderList[colIndex].ExportImageFieldAttribute.Width * 7, ExporterHeaderList[colIndex].ExportImageFieldAttribute.Height); } } catch (Exception) { cell.Value = ExporterHeaderList[colIndex].ExportImageFieldAttribute.Alt; }在ExcelPicture对象中去使用Bitmap对象,对于在线图片源来说,我们会读取并存储到Bitmap中,但是我们发现并没有对该对象进行释放操作,所以导致大量的Bitmap一直没有释放,我们通过using来处理一下。
using (ExcelPicture pic = CurrentExcelWorksheet.Drawings.AddPicture(Guid.NewGuid().ToString(), bitmap)) { AddImage((rowIndex + (ExcelExporterSettings.HeaderRowIndex > 1 ? ExcelExporterSettings.HeaderRowIndex : 0)), colIndex - ignoreCount, pic, ExporterHeaderList[colIndex].ExportImageFieldAttribute.YOffset, ExporterHeaderList[colIndex].ExportImageFieldAttribute.XOffset); CurrentExcelWorksheet.Row(rowIndex + 1).Height = ExporterHeaderList[colIndex].ExportImageFieldAttribute.Height; pic.SetSize(ExporterHeaderList[colIndex].ExportImageFieldAttribute.Width * 7, ExporterHeaderList[colIndex].ExportImageFieldAttribute.Height); }一个带有终结器的新对象是必须要被添加进finalization queue中的,这个行为也被称为“终结注册(registering for finalization)”。
当然我也建议你选择使用SOSEX扩展插件,它提供了finalization类似的内容,似乎看起来更直观一些,如下所示。
下载地址:
:000> .load D:\sosex_64\sosex.dll This dump has no SOSEX heap index. The heap index makes searching for references and roots much faster. To create a heap index, run !bhi 0:000> !finq -stat Generation 0: Count Total Size Type --------------------------------------------------------- 54 2160 System.Drawing.Bitmap 54 objects, 2,160 bytes Generation 1: Count Total Size Type --------------------------------------------------------- 1 184 Microsoft.AspNetCore.Certificates.Generation.CertificateManager+CertificateManagerEventSource 1 336 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.KestrelEventSource 4 1536 System.Net.Sockets.Socket+AwaitableSocketAsyncEventArgs 1 32 Internal.Cryptography.Pal.Native.SafeCertStoreHandle 1 280 System.Net.Sockets.SocketsTelemetry 1 192 System.Threading.Tasks.TplEventSource 1 40 Internal.Cryptography.Pal.Native.SafeCertContextHandle 2 64 Internal.Win32.SafeHandles.SafeRegistryHandle 2 64 Internal.Cryptography.Pal.Native.SafeChainEngineHandle 1 32 Internal.Cryptography.Pal.Native.SafeLocalAllocHandle 1 80 System.Runtime.Loader.DefaultAssemblyLoadContext 1 24 System.WeakReference`1[[System.Runtime.Loader.AssemblyLoadContext, System.Private.CoreLib]] 1 24 System.WeakReference`1[[Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions, Microsoft.AspNetCore.Server.Kestrel.Core]] 2 704 Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketReceiver 2 48 System.WeakReference`1[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.KestrelConnection, Microsoft.AspNetCore.Server.Kestrel.Core]] 1 184 Microsoft.IO.RecyclableMemoryStreamManager+Events 6 960 Microsoft.IO.RecyclableMemoryStream 2 48 System.WeakReference`1[[System.Text.RegularExpressions.RegexReplacement, System.Text.RegularExpressions]] 1 64 CellStore`1[[OfficeOpenXml.ExcelCoreValue, Magicodes.IE.EPPlus]] 1 64 CellStore`1[[System.Object, System.Private.CoreLib]] 1 64 FlagCellStore 2 128 CellStore`1[[System.Int32, System.Private.CoreLib]] 1 64 CellStore`1[[System.Uri, System.Private.Uri]] 2 96 ColumnIndex 2 144 System.Reflection.Emit.DynamicResolver 1 24 System.WeakReference 2 96 PageIndex 302 12080 System.Drawing.Bitmap 1 184 System.Net.NetEventSource 1 40 Interop+WinHttp+SafeWinHttpHandle 8 256 System.Threading.TimerQueue+AppDomainTimerSafeHandle 1 296 System.Net.Http.HttpTelemetry 1 224 System.Net.NameResolutionTelemetry 1 184 System.Net.NetEventSource 1 184 System.Net.NetEventSource 1 360 System.Net.Security.NetSecurityTelemetry 1 24 System.Net.Security.SafeCredentialReference 1 184 System.Collections.Concurrent.CDSCollectionETWBCLProvider 1 48 System.Net.Security.SafeFreeCredential_SECURITY 1 32 Microsoft.Win32.SafeHandles.SafeBCryptAlgorithmHandle 499 objects, 30,736 bytes Generation 2: 0 objects, 0 bytes TOTAL: 553 objects, 32,896 bytes