본문 바로가기

IT 살이/04. 기술 - 프로그래밍

이벤트 핸들러에 의한 메모리 증가

혹시 우리가 아무 걱정없이 사용해왔던 이벤트 핸들러가 어플리케이션의 메모리 증가의 원인이 될 수 있다는 것을 아시나요.

다음 블로그 포스트(http://blogs.msdn.com/tess/archive/2006/01/23/516139.aspx )를 보면 자세한 실험 내용이 나와 있습니다.
이 블로그에서 실험했던 내용을 간단히 정리해보도록 하겠습니다.
 
여기 우리가 흔히 대수롭지 않게 생각했던 코드가 있습니다. 

public class WebForm1 : System.Web.UI.Page
{
  public static MyClassThatHasEvents MyStaticObject = new MyClassThatHasEvents();
 
  private void InitializeComponent()
  {   
   this.Load += new System.EventHandler(this.Page_Load);
   MyStaticObject.StuffHappened += new StuffHappenedEventHandler(this.MyStaticObject_StuffHappened);

  }
...

정적 객체( MyStaticObject)의 이벤트(StuffHappened)에 웹 페이지(WebForm1)에 정의되어 있는 메소드(MyStaticObject_StuffHappened)를 핸들러로 등록하는 코드가 있습니다.
페이지에 정의되어 있는 이벤트 핸들러가 정적 객체의 이벤트 멤버에 의해서 참조되고 있습니다.
따라서 클라이언트의 요청에 대해서 웹 페이지 실행되고 나서도 정적 객체가 여전히 페이지를 참조하고 있기 때문에 페이지 객체는 메모리에 그대로 상주하게 된다는 것입니다.
계속 페이지를 요청하게 되면 메모리는 계속 증가하게 됩니다.
이 상태에서 Garbage collection을 수행해도 페이지 객체들은 여전히 정적 객체의 참조를 받고 있어서 메모리는 완전히 회복되지 않습니다.
만약 이런 종류의 메모리 증가를 막으려면 페이지의 라이프 사이클의 적절한 단계에서 이벤트 핸들러를 명시적으로 제외하는(-=) 코드를 넣어야 합니다.

이런 이벤트 핸들러에 의한 메모리 증가는 많은 윈폼 페이지를 가지고 있는 스마트클라이언트 어플리케이션에서는 더욱더 흔히 일어날 수 있는 일입니다.

요는 이렇다는 것입니다.
페이지보다 오래 남는 객체에 대한 이벤트 핸들러를 등록할때는 주의하라.