가비지 콜렉터는 사용자를 대신하여 메모리를 관리하며 사용하지 않는 객체를 효율적인 방식으로 제거한다
그러나 이 작업이 아무리 효율적이더라도 새로운 객체를 생성하고 삭제하는 일은 그렇지 않은 일에 비해 상대적으로 많은 프로세스 시간을 잡아 먹는다
따라서 가비지 콜렉터가 과도하게 동작하지 않도록 주의해야 함.
1. 자주 사용되는 지역변수를 멤버 변수로 변경
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpriteSetting : System.IDisposable
{
Vector3 position;
Color color;
bool flipX;
bool flipY;
public SpriteSetting (Vector3 position, Color color, bool flipX, bool flipY)
{
this.position = position;
this.color = color;
this.flipX = flipX;
this.flipY = flipY;
}
public void Dispose ()
{
throw new System.NotImplementedException ();
}
public override string ToString ()
{
return string.Format ("[SpriteSetting] : {0}, {1}", this.position, this.color);
}
}
public class GarbageCollectTest : MonoBehaviour {
void Update () {
using (SpriteSetting spriteSetting
= new SpriteSetting(Vector3.zero, Color.red, true, false))
{
Debug.Log (spriteSetting);
}
}
}
실제로 이런 코드를 사용할 일은 없겠지만, 위의 예제에서는 Update 메소드가 호출될 때마다 동일한 SpriteSetting 객체를 계속 생성한다.
가비지콜렉터의 콜렉팅 작업이 수행될 가능성이 높아지고, 호출 주기가 잦으므로 이러한 코드는 상당히 비효율적이다.
이 경우에는 SpriteSetting 객체를 지역변수로 선언할 것이 아니라 변수로 변경하여 객체를 한 번만 생성한 후 이를 재활용할 수 있도록 개선한다.
public class GarbageCollectTest : MonoBehaviour {
SpriteSetting spriteSetting
= new SpriteSetting (Vector3.zero, Color.red, true, false);
void Update () {
Debug.Log (this.spriteSetting);
}
}
2. 종속성 삽입을 활용해 자주 사용되는 객체를 재활용
private static SpriteSetting mySetting;
public static SpriteSetting FavoriteSpriteSetting
{
get
{
if (mySetting == null)
{
mySetting = new SpriteSetting (Vector3.zero, Color.red, true, false);
}
return mySetting;
}
}
이 코드를 보면 FavoriteSpriteSetting을 최초로 요청했을 때 해당 객체를 생성한다.
SpriteSetting 클래스에서는 이렇게 생성된 객체를 저장해두고 동일한 요청이 있을 때 마다 이 객체를 돌려 준다.
객체의 수를 최소한으로 유지하기 위해 객체 생성을 제한하는 방법이다.
생성된 객체가 메모리상에 필요 이상으로 오래 남아 있을 수 있다는 단점은 있다.
3. Immutable 타입을 주의
변경불가능한 타입(Immutable)의 대표적인 예로는 System.String이 있다.
string 객체가 생성되면 객체가 갖고 있는 문자열의 내용은 변경이 불가능하다.
실제로 프로그래밍을 하다보면 문자열의 내용을 변경할 수 있는 것 처럼 보이지만, 새로운 문자열을 가진 string 객체가 생성되는 것이고, 이전 객체는 가비지가 된다.
void Start()
{
string msg = "Hello, ":
msg += "My name is ";
msg += "Debug-Log";
}
앞선 코드는 실제로는 다음과 같은 비효율적인 방법으로 작업이 이루어진다.
string msg = "Hello, ";
string tmp1 = msg + "My name is "; // new string instance
msg = tmp1;
string tmp2 = msg + "Debug-Log"; // new string instance
msg = tmp2;
따라서 string.format이나 StringBuilder를 통해 객체 생성을 최소화 하자.
References
빌 와그너 (2017), Effective C# (3rd Edition), 한빛미디어
'아카이빙 > C#' 카테고리의 다른 글
[Effective C#] 박싱과 언박싱을 최소화하라 (0) | 2018.06.30 |
---|---|
[Effective C#] string.Format()을 보간 문자열로 대체하라 (0) | 2018.06.30 |
[C#] LINQ (0) | 2018.06.26 |
[C#] 람다식 (Lambda Expression) (0) | 2018.06.26 |
[C#] 이벤트와 델리게이트 (0) | 2018.06.25 |