백지부터 시작하는 이세계 코딩 생활

Memory 구조 본문

백지부터 시작하는 이세계 유니티 생활 since 2020

Memory 구조

조아덕 2020. 12. 4. 02:02

 

Memory

데이터의 저장공간. 이 데이터 저장공간에는 여러 데이터 타입들 각각의 저장공간이 존재한다.
보통 data, stack, heap 정도로 분류된다.

C# 의 자료형에는 형식 ( value type )과 참조 형식 ( reference type ) 두 가지 형식(type)이 존재한다.
값 형식 : 해당 변수에 실제 데이터 값을 저장하고 있음.
참조 형식 : 해당 변수는 값이 저장되어 있는 곳의 위치(주소값)를 저장하고 있음.

Heap은 위치가 정해지지 않으며 용량이 큰 대신 느리다. 변수 선언 시 데이터가 저장되어있는 메모리가리킨다.
Stack은 정렬되어 있으며 사용제안이 있는 대신 빠르다. 변수 선언 시 데이터가 저장되어있는 메모리반환한다.

 

static :
프로그램이 실행되었을 때 처음 한 번만 할당되어 프로그램이 종료될 때까지 메모리 영역에 존재하게 된다. 따라서 static 변수는 다른 매서드(Method)에서 공용 변수로 사용할 수 있게 된다.
프로그램이 실행될 때 한 번만 할당된다. 따라서 static 변수의 Life cyccle  프로그램이 종료되기 전까지 이다.
static 변수의 scope 전역변수의 scope와 같다.

 


Stack :
스택(stack)이란 자료가 상자처럼 쌓이는 구조를 의미한다. 따라서 LIFO (Last In First Out) 특징을 가진다.

특정 함수를 호출(=실행)하게 되면 특정 함수만을 위한 메모리 공간이 할당되는데 이 공간을 stack (스택) 이라고 한다.
다시 말해, 함수의 메모리 공간 (stack) 에는 값(지역변수) 형식의 데이터들이 저장된다고 할 수 있다.

함수 수행이 완료되고 결과값이 반환되면 함수가 사용했던 메모리 공간도 함께 사라진다 (해제된다)
따라서 함수 속에 선언되어있던 변수들 (지역변수) 또한 함께 해제된다. ( 코드 블럭이 끝나면 해제된다는 뜻 )

 


Heap :

힙( Heap )이란 프로그램에서 사용하는 동적 메모리 공간을 뜻한다. 이는 객체( Object )가 생성될 때 사용하는 공간이다.

즉, 클래스( Class )가 생성될 때 해당 클래스를 실제로 사용할 수 있도록(실체화) 메모리 공간을 할당받는다. 이 메모리 공간을 힙( Heap )이라고 한다. 힙은 동적으로 할당되며 사용이 끝나면 메모리 해제를 해야한다. 이를 가비지 컬렉터( garbage collector )가 자동으로 처리해 준다. ( GC 에서 처리해줄 때까지 코드 블럭이 끝나도 해제되지 않는다는 뜻 )

클래스가 힙 메모리 공간에 생성된 상태를 인스턴스( Instance )라고 하며 이는 생성된 클래스의 객체( Object )를 의미하기도 한다.
cf. 실체화된 클래스를 인스턴스( Instance )라고 하며 클래스를 가리키는 클래스형 변수를 '참조 변수'라고 한다.

클래스가 생성될 때마다 인스턴스는 매번 다른 메모리 공간을 갖는다. 이는 멤버 변수를 저장하는 공간이 매번 따로 생긴다는 의미이다. 또한 힙 메모리에 생성된 인스턴스는 각각 가상의 주소값을 갖게 된다. 이 가상의 주소값(=참조값)을 Hash Code (해시코드) 라고 하며 참조 변수에 저장된다.

아래 코드와 같이 클래스 생성자를 호출하면 인스턴스가 힙 메모리에 저장된다. 생성된 클래스를 JJOA 변수에 대입하면, JJOA변수는 인스턴스가 저장된 메모리를 가리키게 된다.

Human JJOA = new Human();

/*
다시 말해, Human 클래스 자료형으로 JJOA 변수를 선언하고, 
new Human()로 Human 클래스를 생성하여 
참조변수인 JJOA에 대입한다는 의미이다.
이 참조변수 JJOA는 생성된 인스턴스( Instance )를 가리킨다.
*/

 

 


// 클래스 파일
using UnityEngine;

class Human
{
    public string name;
    public int age;
    public float height;

    public void Eat()
    {
        Debug.Log("Eat, 맛있졍");
    }

    public void Play()
    {
        Debug.Log("Play, 놀자 놀아");
    }

    public void PutOn()
    {
        Debug.Log("PutOn, 옷을 입으세요!");
    }
}
//Object (Instance) 파일
using UnityEngine;

public class ObjectExample : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Human JJOA = new Human();

        JJOA.name = "Duck";
        print("myHeight : " + JJOA.height);
        JJOA.PutOn();
        JJOA.Play();
        JJOA.Eat();
    }
}

 



 

GC ( Garbage Collector )

사용하지 않는 메모리 영역해제하는 역할을 한다.
C# 은 기본적으로 메모리를 자동으로 관리를 해준다.

Stack은 함수 사용이 종료되는 시점에서 변수의 메모리 할당이 해제되기 때문에 특별한 관리가 필요하진 않는다.
Heap 메모리 사용은 두 가지로 나뉘며, Native HeapManaged Heap 두 가지로 분류된다.

Native Heap : 
Unity Engine 에서 사용하는 메모리다. Texture, Asset, Mesh 등을 저장하고 있다. C++로 작성되어 있다.

Managed Heap : 
Mono 에서 관리하는 메모리다. Script에서 할당한 Object, string 타입들을 저장하고 있다.


메모리 할당 :
C#은 선형적인 Heap 메모리를 가지고 있다. 메모리 할당 시 필요한 메모리 크기만큼 증가시키고 0세대 값으로 설정한다.
메모리에는 메모리 할당을 위한 포인터가 있으며 이 포인터는 메로리가 증가된 크기만큼 이동한다.
할당을 위한 메모리가 부족한 경우 GC가 호출되며, 호출 후에도 메모리 공간이 부족한 경우 Heap 메모리가 확장된다 (2배 확장).
그럼에도 불구하고 사용 가능한 메모리 공간이 부족한 경우 앱의 강제 종료가 발생한다.

https://everyday-devup.tistory.com/14

 


메모리 해제 :
Heap 메모리 상에서 사용되지 않는 메모리는 해제시키고, 사용 중인 메모리는 재배치시킨다. 또한 Managed Heap에 할당된 객체의 메모리 허용 임계값을 초과했을 경우 GC.Collect 매서드가 호출되며 메모리가 해제된다. 

https://everyday-devup.tistory.com/14

 

GC 매서드가 호출되고 해제되지 않았던 0세대 메모리들은 1세대로 분류되며, 기존에 해제되지 않았던 1세대 메모리들은 2세대로 재분류된다. 한편, 메모리 군은 0세대 부터 2세대까지 존재하며 메모리 관리는 0세대 부터 시작한다. 
즉, 메모리 공간이 유효하면 0세대군으로 메모리가 계속 할당되며 메모리 공간이 부족할 시 0세대 메모리 부터 체크한다.

https://everyday-devup.tistory.com/14

cf. 85 KB 를 기준으로 Small Object Heap (SOH)과 Large Object Heap (LOH)으로 분류된다. LOH는 2세대로 할당이 시작된다. 

 


Ref.

m.blog.naver.com/PostView.nhn?blogId=baek2sm&logNo=221129030352&proxyReferer=https:%2F%2Fwww.google.com%2F

 

[유니티, C#] 스택과 값, 힙과 참조

스택과 값코드 블록 내에서 선언된 변수는 차례대로 스택에 쌓였다가 코드 블록이 끝나면서 코드 블록에서 ...

blog.naver.com

everyday-devup.tistory.com/10

 

[Unity] C#에서의 메모리

* Heap ▶ 위치가 정해져 있지 않고 용량이 큰 대신 느림 ▶ 참조 타입 ( ex class, string, object ) ▶ 변수 선언 시 데이터가 저장되어있는 메모리를 가리키게 됨 * Stack ▶ 정렬되어 있고 빠르지만 사

everyday-devup.tistory.com

everyday-devup.tistory.com/14

 

[Unity] GC ( 가비지 컬렉터 )

Unity의 가비지 컬렉터에 대해 설명하고자 한다. C# 은 기본적으로 메모리를 자동으로 관리 해줌 * C# 메모리 : https://everyday-devup.tistory.com/10 [Unity] C#에서의 메모리 * Heap ▶ 위치가 정해져 있지..

everyday-devup.tistory.com

pandasom.tistory.com/18

 

유니티 기술면접 준비 // 박싱, 언박싱, 값,참조

값 형식과 참조 형식의 차이 [값형식] -메모리의 Stack에 할당된다. -변수에 값이 직접 저장됨.(Stack) -기본 생성자는 예약되어 있음. (Object와 String을 제외한 모든 형식은 값 기반 형식임) [참조형식]

pandasom.tistory.com

 

'백지부터 시작하는 이세계 유니티 생활 since 2020' 카테고리의 다른 글

Inheritance  (0) 2020.12.09
Object Pool  (0) 2020.12.04
Shader  (0) 2020.12.01
Angular Drag, Mass, Drag  (0) 2020.12.01
Class 와 Object 와 Instance  (0) 2020.12.01
Comments