Para los futuros alumnos del curso "C # Developer" y todos los interesados, preparamos una traducción de material útil.
También lo invitamos a participar en el seminario web abierto sobre el tema "Métodos LINQ que hacen todo por usted" , donde los participantes discutirán seis representantes de la familia de tecnologías LINQ, tres componentes de la operación de consulta principal, ejecución diferida e inmediata, consultas paralelas.
Cualquiera que haya trabajado en un gran proyecto corporativo sabe que las pérdidas de memoria son como ratas en un gran hotel. Es posible que no los note cuando hay pocos, pero siempre debe estar atento en caso de que se reproduzcan, se cuelen en la cocina y ensucien todo a su alrededor.
, — . 8 , .NET , . , , . , .
.NET
« » . , (GC — garbage collector), ?
. — , , . , , , . , , event
.
, - ( ) . . .NET , . , , , , . Dispose
, ( ). .NET ., Marshal
PInvoke
( ).
:
1.
Debug | Windows | Show Diagnostic Tools, . -, , , Visual Studio, . . 2 : GC Pressure ( ).
, (Process Memory) :
, , , , - .
GC Pressure, :
GC Pressure — , . , , .
, , , . Visual Studio Enterprise , . .
2. , Process Explorer PerfMon
— (Task Manager) Process Explorer ( SysInternals). , . , , .
PerfMon , . , , . Process | Private Bytes.
, . , . , / , (). , GC Pressure. , , .
, , . , - ( ).
3.
-. . ( ), , .
.NET: dotMemory, SciTech Memory Profiler ANTS Memory Profiler. «» , Visual Studio Enterprise.
, , GC Root.
GC Root — , , , GC Root, . , , GC Roots. « .NET».
— , . , . , :
, SciTech , :
4. «Make Object ID»
5 , - C# .NET, , , Finalizer. , . Make Object ID (Immediate Window).
, , . , , . , , :
, .
, ,
Make Object ID
.Immediate $1
, ,Object ID
.
, .
.
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
5. $1
. null
, , . , .
:
, :
, , .
: .NET Core 2.X (). , , . , , .
5.
, , . , .
:
(Events) .NET , . , , . , : 5 , - C# .NET,
, , , . , GC Roots, .
— . , OutOfMemory. .
WPF . — DependencyObject INotifyPropertyChanged. , WPF ( ViewModel) , . WPF StackOverflow.
. , , , — . :
public class MyClass
{
private int _wiFiChangesCounter = 0;
public MyClass(WiFiManager wiFiManager)
{
wiFiManager.WiFiSignalChanged += (s, e) => _wiFiChangesCounter++;
}
, . Live Stack GC Root. , , , . . , . :
public class MyClass
{
public MyClass(WiFiManager wiFiManager)
{
Timer timer = new Timer(HandleTick);
timer.Change(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
}
private void HandleTick(object state)
{
// do something
}
6. Dispose
.NET . .NET , Win32 API. , , , , , , .
.NET Framework
, , IDisposable
. , , Dispose
. — Dispose
. , using
.
public void Foo()
{
using (var stream = new FileStream(@"C:\Temp\SomeFile.txt",
FileMode.OpenOrCreate))
{
// do stuff
}// stream.Dispose() will be called even if an exception occurs
using
try / finally
, Dispose
finally
.
Dispose
, , .NET
Dispose. , Dispose
, Finalizer
, . , Finalizer
.
, Dispose
. :
public class MyClass : IDisposable
{
private IntPtr _bufferPtr;
public int BUFFER_SIZE = 1024 * 1024; // 1 MB
private bool _disposed = false;
public MyClass()
{
_bufferPtr = Marshal.AllocHGlobal(BUFFER_SIZE);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
// Free any other managed objects here.
}
// Free any unmanaged objects here.
Marshal.FreeHGlobal(_bufferPtr);
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass()
{
Dispose(false);
}
}
— . , ( Finalizer
), Dispose()
.
GC.SuppressFinalize(this)
. , Finalizer
, . Finalizer- . Finalizer
F-Reachable-Queue
, . .
7.
. , , . , - , . , , .
. :
Process currentProc = Process.GetCurrentProcess();
var bytesInUse = currentProc.PrivateMemorySize64;
PerformanceCounter
— , PerfMon
:
PerformanceCounter ctr1 = new PerformanceCounter("Process", "Private Bytes", Process.GetCurrentProcess().ProcessName);
PerformanceCounter ctr2 = new PerformanceCounter(".NET CLR Memory", "# Gen 0 Collections", Process.GetCurrentProcess().ProcessName);
PerformanceCounter ctr3 = new PerformanceCounter(".NET CLR Memory", "# Gen 1 Collections", Process.GetCurrentProcess().ProcessName);
PerformanceCounter ctr4 = new PerformanceCounter(".NET CLR Memory", "# Gen 2 Collections", Process.GetCurrentProcess().ProcessName);
PerformanceCounter ctr5 = new PerformanceCounter(".NET CLR Memory", "Gen 0 heap size", Process.GetCurrentProcess().ProcessName);
//...
Debug.WriteLine("ctr1 = " + ctr1 .NextValue());
Debug.WriteLine("ctr2 = " + ctr2 .NextValue());
Debug.WriteLine("ctr3 = " + ctr3 .NextValue());
Debug.WriteLine("ctr4 = " + ctr4 .NextValue());
Debug.WriteLine("ctr5 = " + ctr5 .NextValue());
perfMon, .
. CLR MD (Microsoft.Diagnostics.Runtime) . , , , . .
, CLR MD, DumpMiner .
, , , Application Insights.
8.
— . . , :
[Test]
void MemoryLeakTest()
{
var weakRef = new WeakReference(leakyObject)
// Ryn an operation with leakyObject
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Assert.IsFalse(weakRef.IsAlive);
}
, .NET Memory Profiler SciTech dotMemory, API:
MemAssertion.NoInstances(typeof(MyLeakyClass));
MemAssertion.NoNewInstances(typeof(MyLeakyClass), lastSnapshot);
MemAssertion.MaxNewInstances(typeof(Bitmap), 10);
, , , , : .