C# - 인스턴스가 살아 있어 메모리 누수가 발생하고 있는지 확인하는 방법
아래와 같은 상황에서,
WPF - WindowsFormsHost를 담은 윈도우 생성 시 메모리 누수
; https://www.sysnet.pe.kr/2/0/12340
메모리 누수의 원인이... 의심이 가는 "그 인스턴스"가 살아 있어 발생하는 것인지 어떻게 확인할 수 있을까요? 그런 용도로 존재하는 것은 아니지만, WeakReference를 사용하면 그 목적을 이룰 수 있습니다.
예를 들어 위의 글에서 다룬 소스 코드의 MainWindow 측에 WeakReference를 이용해 약간의 코드를 더 추가해 보겠습니다.
using System;
using System.Collections.Generic;
using System.Windows;
namespace WpfApp5
{
public partial class MainWindow : Window
{
System.Windows.Threading.DispatcherTimer _dispatcherTimer;
Queue<WeakReference> _list = new Queue<WeakReference>();
public MainWindow()
{
InitializeComponent();
_dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
_dispatcherTimer.Tick += _dispatcherTimer_Tick;
_dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
_dispatcherTimer.Start();
}
private void _dispatcherTimer_Tick(object sender, EventArgs e)
{
Queue<WeakReference> copyList = new Queue<WeakReference>();
while (_list.Count > 0)
{
WeakReference wr = _list.Dequeue();
if (wr.Target != null)
{
copyList.Enqueue(wr);
}
}
_list = copyList;
System.Diagnostics.Trace.WriteLine(_list.Count);
GC.Collect(2, GCCollectionMode.Forced);
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var window = new Window1();
window.Show();
WeakReference wr = new WeakReference(window);
_list.Enqueue(wr);
}
}
}
결과 비교를 위해 우선 메모리 누수가 발생하는 걸 확인해 봐야겠죠? 이를 위해 "Window1"의 OnClosed에서 WindowsFormsHost.Dispose 호출을 주석 처리한 후,
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
protected override void OnClosed(EventArgs e)
{
// clsInstance.Dispose();
base.OnClosed(e);
}
}
Visual Studio에서 F5(Start Debugging) 키를 눌러 실행, "Button"을 누를 때마다 Output 창에 나오는 WeakReference.Target 속성 값이 살아 있는 수가 출력되고, 바로 그것이 쌓이면 메모리 누수가 되는 것입니다.
반면, 해당 주석을 다시 풀고 실행해 보면, 이제 GC.Collect로 인해 WindowsFormsHost 개체들이 정상적으로 GC 수집이 되므로 Button을 누를 때마다 Output 창에는 잠시 수가 늘었다가 0으로 내려가는 것을 볼 수 있습니다. 간단하죠?! ^^
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]