[Effective C#] 불필요한 객체를 만들지 말라

WH_NAM·2024년 2월 26일

Effective C#

목록 보기
15/23
post-thumbnail

Effective C# Item 15

지역변수를 멤버변수로

protected override void OnPaint(PatintEventArgs e)
{
	// 나쁜 예 : Paint 이벤트가 발생할 때마다 동일한 폰트를 생선하다.
    using (Font MyFont = new Font("Arial", 10.0f))
    {
    e.Graphics.DrawSTring(DateTime.Now.ToString(), 
    						MyFont, Brushes.Balck, new PointF(0, 0));
    }

    base.OnPaint(e);
}

이벤트 핸들러가 호출될 때마다 동일한 Font 객체를 매번 다시 생성한다. 가비지 수집기는 이렇게 생성된 객체를 제거해야 하는 작업을 수행한다.

protected override void OnPaint(PaintEventArgs e)
{
	e.Graphics.DrawString(DateTime.Now.ToString(),
    						_myFont, Brushes.Black, new PointF(0, 0));

    base.OnPaint(e);
}

Paint 이벤트가 발생할 때마다 새로운 가비지가 생성되지 않으므로 가비지 수집기가 해야하는 일의 양도 줄게 된다.

호출빈도가 빈번하지 않은 경우라면 굳이 변경할 필요가 없다.

종속성 삽입
자주 사용되는 참조타입의 인스턴스를 정적 멤버 변수로 선언한다.

private static Brush _blackBrush
{
	public static Brush Black
    {
    	get
        {
        	if (_blackBrush == null)
            	_blackBrush = new SolidBrush(Color.Black);
            return blackBrush;
        }
    }
}

최초로 요청했을 때 해당 객체를 생성하고 생성된 검정 브러시를 저장해둔다. 검정 브러시 하나를 영원히 재사용하게 된다.

경우에 따라서는 생성된 객체가 메모리상에 필요 이상으로 오랫동안 남아 있을 수 있다. 또한 Dispose()메서드를 호출해야할 시점을 결정할 수 없기 때문에 비관리 리소스를 삭제할 수 없다는 것도 단점이다.

변경 불가능한 타입
변경 불가능한 타입의 대표적인 예로는 System.String이 있다. string 객체가 생성되면 이 객체가 가지고 있는 문자열의 내용은 수정이 불가능하다. 따라서 string 문자열을 수정하면 새로운 문자열을 가진 새로운 string 객체가 생성된다.

public static void Main(string[] args)
{
	string msg = "Hello, ";
    msg += thisUser.Name;
    msg += ". Today is ",
    msg += System.DateTime.Now.ToString();
}

이와 같이 코드를 작성했다면 매우 비효율적으로 작업이 이루어진다.
총 3개의 가비지가 생성되는 것이다.

다음과 같은 방법을 추천한다.

// 문자열 보간
string msg = string.Format("Hello, {0}. Today is {1}" , thisUser.Name, DateTime.Now.ToString());

// StringBuilder
StringBuilder msg = new STringBuilder("Hello, ");

msg.Append(thisUser.Name);
msg.Append(". Today is ");
msg.Append(DateTime.Now.ToSTring());

string finalMsg = msg.ToSTring();

결론
GC는 응용프로그램이 사용하는 메모리를 효율적으로 관리한다. 하지만 힙에서 객체를 생성하고 삭제하려면 여전히 시간이 필요하다. 객체를 과도하게 생성하는 것을 피하고 불필요한 객체를 생성하지 말라.

profile
안녕하세요

0개의 댓글