C# 内存释放 IDisposable 与 析构方法的 关系
xx.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
</Project>
Program.cs
#define RUNDISPOSE // 注释预定义切换
using System;
using System.Runtime.InteropServices;
namespace Cmd
{
class Program
{
static void Main(string[] args)
{
Test();
GC.Collect();
Console.WriteLine("Memory used after full collection: {0:N0}", GC.GetTotalMemory(true));
Console.WriteLine("Hello World!");
}
public static void Test()
{
unsafe
{
#if RUNDISPOSE
using var _net = new NetworkChangeCleanup(int.MaxValue);
#else
var _net = new NetworkChangeCleanup(int.MaxValue);
#endif
Console.WriteLine("size: {0}", Marshal.SizeOf<NetworkChangeCleanup>(_net));
Console.WriteLine("object is {0}.", _net._handler.ToString());
}
}
}
[StructLayout(LayoutKind.Sequential)]
sealed class NetworkChangeCleanup : IDisposable
{
public int _handler;
public NetworkChangeCleanup(int handler)
{
_handler = handler;
}
// If user never disposes the HttpClient, use finalizer to remove from NetworkChange.NetworkAddressChanged.
// _handler will be rooted in NetworkChange, so should be safe to use here.
~NetworkChangeCleanup() => Console.WriteLine("Finalized.");
public void Dispose()
{
_handler = 0;
Console.WriteLine("disposed.");
#if RUNDISPOSE
GC.SuppressFinalize(this); // 试试注释该方法
#endif
}
}
}