정보처리기사 필기를 공부할 때 스택과 힙에 관해 공부했던 것 같은데 합격하고 잊고있다보니 다 까먹어버렸다.

우리가 프로그램을 사용하거나 코드를 실행할 때 운영체제는 미리 메모리 공간을 할당해준다.

메모리 구조 중에 스택과 힙에 대해 간단하게 정리를 해보려고 한다.

 

우선 참고

https://developer-talk.tistory.com/50

 

[C#]값 형식(Value Types)과 참조 형식(Reference Types)

값 형식(Value Types)과 참조 형식(Reference Types) C#에서는 메모리에 공간에 데이터를 할당하는 두 가지 방법이 있습니다. 값 형식(Value Types)은 스택(Stack) 공간에 데이터를 할당하며, 참조 형식(Referenc..

developer-talk.tistory.com

https://junghyun100.github.io/%ED%9E%99-%EC%8A%A4%ED%83%9D%EC%B0%A8%EC%9D%B4%EC%A0%90/

 

스택(Stack)과 힙(Heap) 차이점

해당 Post는 스택(Stack)과 힙(Heap) 차이점를 정리한 파일이다.

junghyun100.github.io

 

* 간단 요약

값 형식은 스택(Stack) 공간에 데이터를 할당

참조 형식은 힙(Heap) 공간에 데이터를 할당

메서드를 통해 생성된 변수는 스택( Stack)에 할당
new 한정자를 이용한 변수,  오브젝트나 클래스를 참조하는 형식은 힙(Heap)에 할당

값 형식(Value Type)

데이터 값 자체가 스택 메모리 영역에 바로 저장이 된다.

함수를 시작하면 데이터가 순차적으로 생성되고, 함수가 끝난다면 데이터가 순차적으로 소멸된다.

대체로 숫자 형식(byte,short,int,float 등)과 논리 형식(bool)이 해당된다.

 

참조 형식(Reference Type)

데이터 값이 힙 메모리 영역에 할당되고, 가비지 컬렉터(GC)에 의해 해제된다.

변수가 값 대신에 값이 있는 곳의 위치를 담는 데이터 형식이다.

대체로 문자열, 배열(Array), 클래스(Class), Object 형식이 해당된다.

 

스택(Stack)

- 정적으로 메모리에 할당

- 스택 영역에 있는 변수들은 선언된 함수를 빠져나가면 없어진다.

- 액세스가 빠르다.

- 지역 변수가 해당된다.

- 변수의 크기를 조정할 수 없다.

// 함수 시작한다~
float a = 10.5f;
int b = 20;

a = 30.5f;
b = 25;
// 함수 끝났다 ~

 

힙(Heap)

- 동적으로 메모리에 할당

- 스택보다 액세스가 느리다

- 개발자가 원하는 시점에 동적으로 메모리 할당 가능, 이러한 유형의 변수가 할당되는 영역이 힙(Heap)

- 전역 변수가 해당된다.

- 가비지 컬렉터는 힙 영역에서 사용되지 않는 데이터들을 소멸시킴

*(가비지 컬렉터는 다음 기회에 글 쓰기로... 이것 때문에 해제를 꼭 해줘야 한다. 라는 것만 알고 있자.)

Public Class PlayerMove:MonoBehavior
{
	private float moveSpeed = 2f; // 전역변수 힙
    private float rotateSpeed = 2f; // 전역변수 힙
    
    public void Player()
    {
    	playerStatus status = New playerStatus(); // new 힙
    }
}

 

난 유니티를 사용하면서 property(속성)가 있는 줄도 몰랐었다.

여러 에셋들의 소스코드를 까보면 자주 보이기도 하고, 공부해보니까 자주 쓰면 좋겠다 싶어서 글을 정리하기로 했다.

 

참고한 블로그

https://arainablog.tistory.com/102

 

get 접근자, set 접근자

- 참고 링크 속성은 필드 및 메서드 모두의 측면을 결합합니다.Properties combine aspects of both fields and methods. 개체의 사용자에게 속성은 필드로 표시되며, 속성에 액세스하려면 동일한 구문이 필요합

arainablog.tistory.com

https://itmining.tistory.com/34

 

[유니티 C# 기초 강의] 9. 프로퍼티

이 글은 PC 버전 TISTORY에 최적화 되어있습니다. 서론 프로퍼티(Property)는 속성이라는 의미를 가지고 있습니다. 클래스에서 멤버 변수를 속성이라고도 하는데 우리는 정보은닉을 위해 이를 private

itmining.tistory.com

 

1.Property(속성) 특징

1. C#에서 사용가능한 데이터 접근 방식 중에 하나이다.

2. get 속성 접근자는 속성 값을 반환 / set접근자는 새 값을 할당하는데 사용

3. set 속성 접근자의 value 키워드는 set 접근자가 할당하는 값을 정의할 때 사용

4. get은 외부에서 해당 프로퍼티에 접근하여 읽어야 하는 상황에서 호출

5. set은 외부에서 해당 프로퍼티에 접근하여 값을 할당하는 상황에서 호출

6. 유니티의 인스펙터창에서 보이지 않는다.

 

- 외부에서 클래스 변수에 값을 할당 할 때, 변수의 값이 변경되었을 때를 감지하여, 다른 함수나 동작을 실행하길 원한다.

- 해당 변수를 여러 곳에서 가져가서 조건을 사용하는 것을 편하게 하기 위해서 사용한다.

 

1.Property(속성) 사용방법

 

자동으로 구현되는 프로퍼티

- 프로퍼티를 사용해 클래스의 변수에 대해 감추고 사용하기 위함 / 코드가 간단함.

- private 변수를 생성하지 않고 프러퍼티 자체를 사용한다.

- 조건이 없고, 단순히 변수 값을 할당하거나 반환 용도

- get, set 접근자 안에 아무것도 쓰지 않으면 프로퍼티 그 자체를 사용할 수 있다.

 

간단한 사용 예시이다.

public class PlayerInfo
{
    public string nickName {get; set;}
    public int level {get; set;}
    public int hp {get; set;}
    public int mp {get; set;}
}
PlayerInfo playerinfo;

void Start()
{
	playerinfo.nickName = "Simbble";
    playerinfo.level = 26;
    playerinfo.hp = 100;
    playerinfo.mp = 50;
}

void Update()
{
	if(Input.GetKeyDown(Keycode.E))
    {
    	Debug.Log(playerinfo.nickName);
        Debug.Log(playerinfo.level);
        Debug.Log(playerinfo.hp);
        Debug.Log(playerinfo.mp);
    }
}

 

 

 

프로퍼티 사용

- 변수의 값이 개발자가 원하는 범위로 조건을 둘 수 있다.

- set 접근자 내에 변수가 변했을 때, 다른 함수나 동작을 실행할 수 있다.

- 클래스가 구현 또는 코드를 숨기는 동시에 값을 가져오고 설정하는 법을 공개적으로 노출할 수 있다.

using UnityEngine;
using ~~~~~~~~~~~;

public class Player : MonoBehaviour
{
    private int hp;

    public int PlayerHP
    {
        get 
        {
            return hp; // 속성 값을 반환
        }
        set 
        {
            if(value<10)
            {
                Debug.Log("해독제를 사용했습니다.")
            }
            else
            {
                hp = value;
            }
        }

        void Start()
        {
            PlayerHP = 5; // 해독제를 사용했다는 디버그가 찍히겠죠.
            // playerHP = 15; // 플레이어의 체력이 바뀌고 끝나겠죠.
        }
    }
}

 

Static의 위험성

static : 정적, 고정

변할 일이 없고 객체와 상관없는 필드나 메소드에 사용이 가능하다. 풀어서 이야기 하자면,

Static이란,
변수 / 함수 / 클래스에 정적(static) 속성을 부여하여 클래스에서 객체를 생성하지 않고 변수나 함수를 호출 기능

굉장히 편해보이는 기능이지만, 남발 해서는 안되는 이유가 있다.

static을 선언하는 즉시(컴파일 타임) 데이터에 저장이 된다.(런타임 이전에 이미 생성)

그리고 어플리케이션을 종료하기 전까지 쭉 가지고 있다.

 

사용하지 않을 때나 필요하지 않을 때에도 갈비지컬렉터(GC)가 실행되지 않기 때문에 메모리 낭비가 심하다.

 

따라서 거의 변할 일이 없는 변수나 함수에만 사용하는 것을 권장한다.

편하다고 막 사용하다가 본인이 만들고 있는 프로젝트의 악영향을 많이 끼칠 수 있기 때문이다.

 

Static의 사용방법

 

예시 1) static 함수가 

한번 선언하면 없어지지 않는 특징을 이용하여 이런 식으로 사용이 가능하다.

// static 속성의 변수 생성
using ~~~

public Class Settings
{
	// static으로 만들어진 값은 모든 클래스의 인스턴스 공유
	public static int playerCount = 0;
    
    public Settings()
    {
    // 이 클래스로 만든 객체의 개수 파악용. 참조할 때마다 1씩 늘어날 것이다.
   	 playerCount++;
    }
}

만약 다른 클래스에서 객체로 생성한다면,

// Settings 클래스의 static 변수 사용
Public Class Game()
{
	void Start()
    {
    	Settings gameStart1 = new Settings();
        Settings gameStart2 = new Settings();
        Settings gameStart3 = new Settings();
        
        int callCount = Settings.PlayerCount;
        
        Debug.Log(callCount);
    }
}

callCount의 디버그는 3이 찍힐 것이다.

 

 

글 쓰다 보니까 static을 쓸곳이 있긴 할까? 싶어서 나중에 중요하다 생각하면 글을 갱신해야겠다

일단 여기까지.

 

Dictionary를 검색해보면 자료구조에 시간복잡도와 여러가지가 많은데 솔직히 이런 거는 아직은 잘 모르겠다.

코딩 알고리즘 사이트에도 많이 사용하는 것 같은데 나는 Dictionary를 잘 사용하지 않았다.

이참에 사용법을 간단하게 알아볼 생각으로 글 작성을 한다.


Dictionary

 

Key , Value를 이용하여 자료를 저장하고 편하게 찾을 수 있는 기능입니다.

쉽게 보기 위해 몬스터의 이름과 몬스터의 체력을 저장해서 디버그를 찍어봅시다.

Dictionary 사용 예시
몬스터의 체력들

이 경우에는 몬스터 이름이 Key가 되고 10이 Value가 되겠습니다.

이 자료구조를 사용하면 굉장히 편하게 입맛에 따라 사용할 변수를 짝 지어 줄 수 있을 것 같습니다.


ContainsKey

 

Dictionary 자료구조를 사용한 여러 예시를 봐보면 ContainsKey라는 메서드가 자주 보입니다.

이 메서드는 Dictionary에 키를 추가하는 경우 키가 중복하는지 확인을 할 때에 쓰입니다.

아주 간단한 예시입니다.

이미 슬라임이 Dictionary에 존재 하기 때문에 이미 슬라임이 존재한다는 디버그가 찍힙니다.

만약 슬라임이 Dictionary에 존재하지 않았다면 "슬라임 추가 성공!" 이라는 디버그가 찍혔겠죠?

 

반복문으로 Dictionary에 값을 추가하고 싶거나 조건을 넣고 싶을 때 사용하기 좋아보입니다.

유니티를 사용할 때에 스크립트를 만들면 항상 클래스 옆에 MonoBehavior가 적혀있습니다.

별거 아니겠지 하고 깊게 생각 안 하고 코딩을 했었는데, 다른 사람의 코드를 보면

MonoBehavior 대신 다른 단어가 써져있거나 없었을 때도 보았을 것입니다.

 

MonoBehavior는 왜 있을까?


MonoBehavior의 특징

 

Unity에서 제공하는 모든 스크립트가 상속되어 있는 클래스입니다. 유니티에서 정말 많이 사용하는 것 중에서

대표적인 것으로는 Awake, Start, Update 등이 MonoBehavior가 있어야 사용이 가능합니다.

 

MonoBehavior의 상속받는 대상은 [MonoBehavior -> Behavior -> Component -> Object] 입니다.

 

유니티에서 스크립트를 생성하면 기본적으로 MonoBehavior가 달려 있는 이유가 바로 이 때문인데,

의미는 MonoBehavior 클래스를 상속하겠다. 입니다. 이걸 더 쉽게 풀어서 말하자면

이 클래스에서 유니티에서 제공하는 스크립트의 기능을 사용하겠다. 라는 뜻입니다.

 

여기서 MonoBehavior에서 사용 가능한 함수들의 종류를 볼 수 있습니다.

https://docs.unity3d.com/kr/530/ScriptReference/MonoBehaviour.html

 

UnityEngine.MonoBehaviour - Unity 스크립팅 API

MonoBehaviour is the base class from which every Unity script derives.

docs.unity3d.com


 

MonoBehavior가 상속된 클래스의 특징

 

1. 스크립트 파일 자체로는 사용이 불가능하고, GameObject의 Component로 등록을 해야 사용을 할 수 있습니다.

(이와 마찬가지로 MonoBehavior을 상속받지 않는 클래스라면 Component로 등록이 불가능합니다.)

 

2. 다른 클래스에서 해당 스크립트를 사용하고 싶다면 GetComponent<>함수를 사용해야 합니다.

 

3. new로 동적 할당을 할 수 없습니다.

- 만약 동적할당을 하고 싶다면 ExampleSrc exSrc = 게임오브젝트.AddComonent<exsrc>();를 사용하면 됩니다.

 


MonoBehavior 상속된 클래스 사용 주의사항

 

Update, FixedUpdate 등 프레임 단위로 빠르게 반복으로 실행하는 함수는 안에 아무런 내용이 없더라도 실행되어

성능에 안 좋은 영향을 끼칩니다. 만약 사용하지 않는다면 무조건 삭제를 해주어야 성능 향상에 도움이 됩니다.

일기장

블로그 시작

2022. 7. 23. 18:39

Start - 2022.07.23

블로그에 쓸 글 : 개발글/ 일기, 맛집, 여행

블로그 개설 이유 : 공부 기록, 이직할 때 어필 / 취미, 일기장 및 정보공유 목적