2014년 1월 26일 일요일

C# 메모리 관리 기법 - instance

C#에서 클래스를 인스턴싱할때는 new를 해서 할 수 있습니다. 그런데 이런 식으로 생성하게 되면 heap에 메모리가 할당됩니다. 

그리고 이런것들이 계속 누적이 되면 가비지가 작동하게 됩니다. 

아래 예를 보세요.
static class TestMyVector
{
    public static void PrintVectorLength(float x, float y, float z)
    {
        // 이런것들이 heap에 메모리가 할당됩니다. 
        Vector3 v = new Vector3(x, y, z);
        Debug.log("v의 값 X = " + v.x  + "V의 값 Y = " + v.y + "V의 값 Z = " + v.z);
    }
}
이런 경우에 Vector 클래스를 구조체로 바꾸면 new를 통해서 생성하게 되도 heap에 메모리가 할당되지 않게 됩니다. 
구조체는 Value type이기때문에 stack에 할당되기 때문입니다. 
이런식으로 해서 가비지를 조금이라도 줄일 수 있습니다. 
아래의 예처럼요.
public class MyVector
{
    // 이런식으로 구조체를 만들고
    public struct MyVector
    {
        public float x, y, z;

        public MyVector(float x, float y, float z) 
        { 
            this.x = x;
            this.y = y; 
            this.z = z;
        }
    }
}

static class TestMyVector
{
    public static void PrintVectorLength(float x, float y, float z)
    {
        // 구조체를 이용해서 인스터스하면 이것은 stack에 할당됩니다.
        MyVector v = new MyVector(x, y, z);
        Debug.log("v의 값 X = " + v.x  + "V의 값 Y = " + v.y + "V의 값 Z = " + v.z);
    }
}
그런데 경우에 따라서는 구조체로 만드는 것이 애매한 경우가 있습니다. 
이런 경우엔 멤버변수로 만들어서 사용하는 방법이 있습니다. 
저도 주로 이 방법을 사용하는데요.. 가장 간편하기도 하고 멤버변수로 만들 경우 메서드 인자를 줄일수도 있고 여기 저기 사용하기 편하다는 장점도 있습니다. 
대신 잘못했을 경우 값이 도중에 바뀌어서 애매한 버그를 만들기도 합니다. ^^;;
하지만 개인적으로는 이 방법을 추천합니다. 
아래와 같이 멤버변수로 만들어서 사용할 수 있습니다. 
static class TestMyVector
{
    // 멤버변수로 만들어 놓습니다. 
    Vector3 tempVector3 = new Vector3(0.0f, 0.0f, 0.0f);

    // 이해를 돕기 위해 위와같이 만들었지만 x, y, z의 값이 모두 0인 경우
    // new를 사용하지 않고 
    // Vector3 tempVector3 = Vector3.zero
    // 이와 같이 쓸수도 있습니다. 

    public static void PrintVectorLength(float x, float y, float z)
    {
        tempVector3.x = x;
        tempVector3.y = y;
        tempVector3.z = z;
        Debug.log("tempVector3의 값 X = " + tempVector3.x  + "tempVector3의 값 Y = " + tempVector3.y + "tempVector3의 값 Z = " + tempVector3.z);
    }
}


댓글 없음:

댓글 쓰기