В ядре C #,
У меня есть огромный массив двоичных данных, который мне нужно использовать в своем коде, и мне нужно освободить выделенную память по окончании его использования.
Кодработает в Docker для Linux (с использованием базовых образов: microsoft / dotnet: 2.1-sdk + microsoft / dotnet: 2.1-runtime) - я вижу, что использование кучи всегда становится больше (htop).
byte[] arr = new byte[1024 using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
namespace TestHeap
{
public class DisposeArr : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Instantiate a SafeHandle instance.
SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
byte[] Data { get; set; }
public DisposeArr(long size)
{
Data = new byte[size];
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
Data = null;
handle.Dispose();
// Free any other managed objects here.
//
}
disposed = true;
}
~DisposeArr()
{
Dispose(false);
}
}
class Program
{
public void Run()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("total mem:{0}", GC.GetTotalMemory(false)); GC.Collect();
using (DisposeArr newArr = new DisposeArr(1024 * 1024 * 1024))
{
}
// byte[] arr = new byte[1024 * 1024 * 1024];
Console.WriteLine("New. total mem:{0}", GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Collect. total mem:{0}", GC.GetTotalMemory(false));
GC.WaitForPendingFinalizers();
Console.WriteLine("Pending. total mem:{0}", GC.GetTotalMemory(false)); GC.Collect();
GC.Collect();
Console.WriteLine("Collect. total mem:{0}", GC.GetTotalMemory(false));
}
Console.ReadLine();
}
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
}
}
1024];
Console.WriteLine("array in gen:{0}", GC.GetGeneration(arr));
// Массив находится в поколении 2.
Когда я делаю:
Console.WriteLine("total mem before:{0}", GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("total mem after:{0}", GC.GetTotalMemory(false));
Память, выделенная массивом, не распределяется, и сбор, кажется, не работает немедленно?
Я попытался также поместить arr в IDisposable, но может ли это помочь?
public class DisposeArr : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Instantiate a SafeHandle instance.
SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
byte[] Data { get; set; }
public DisposeArr(long size)
{
Data = new byte[size];
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
Data = null;
handle.Dispose();
// Free any other managed objects here.
//
}
disposed = true;
}
~DisposeArr()
{
Dispose(false);
}
}
и в основном коде:
using (DisposeArr newArr = new DisposeArr(1024 * 1024 * 1024))
{
}
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("total mem before:{0}", GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("total mem after:{0}", GC.GetTotalMemory(false));
Как я могу заставить этопамять, выделенная массивом, будет расположена сразу после «GC.Collect»?
Вот полный код.Код может работать, но если есть 100% и 95% (почти память), может быть некоторая утечка памяти (и на докере - в linux - это может привести к утечке памяти).
*1024*
Спасибо.