Pour les futurs étudiants du cours "C # Developer" et tous ceux qui sont intéressés, nous avons préparé une traduction de matériel utile.
Nous vous invitons également à participer au webinaire ouvert sur le thème «Les méthodes LINQ qui font tout pour vous» - où les participants discuteront de six représentants de la famille de technologies LINQ, de trois composants de l'opération de requête principale, de l'exécution différée et immédiate, des requêtes parallèles.
Quiconque a travaillé sur un grand projet d'entreprise sait que les fuites de mémoire sont comme des rats dans un grand hôtel. Vous ne les remarquerez peut-être pas quand ils sont peu nombreux, mais vous devriez toujours être à l'affût au cas où ils se reproduiraient, se faufiler dans la cuisine et salir tout autour.
, — . 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);
, , , , : .