1.컴퓨터 
저장 장치
하드디스크 -  컴퓨터에 물리적으로 파일을 저장
메모리 - 프로그램/어플리케이션이 실행하는데 필요한 데이터를 저장 
ex) 게임 - 레벨,소유골드 등등...

메모리는 배열처럼 생겼다 (배열은 아님!!!!)
Code : 프로그래머가 작성한 코드를 보관
Data : static,const 어플리케이션 전반에 필요한 데이터 저장
Heap : 참조 데이터 (객체) 저장
Stack : 로컬변수 ,매개변수 저장
어플리케이션 실행 순서에 필요한 데이터 보관

메모리는 2진수로된 주소값이 있다.
해당 메모리에 접근하기 위해 주소값을 가지고 있으면 된다 -> C/C++의 포인터 기능

int x = 10; 
해당 데이터(10)는 stack영역 메모리 첫번째에 저장된다.
메모리 첫번쨰는 0000 0000주소값을 가지고있는데

해당 데이터에 접근하기 위해 0000 0000 주소값을 가져오는게 아닌 x로 변경하여 사용하게 되는것이다.
x도 stack 영역에 저장됨

= : Rvalue를 Lvalue로 옮겨주는것이다.

class는 참조값이기에 heap 영역에 추가됨
heap은 어디에 저장되는지 모름, 그리고 알 필요도 없기에 빈 어딘가에 저장된다고 생각하면 됨

Class Person 
Class Data는 heap영역에
Calss로 만들어진 객체는 Stack 영역에 저장됨

사용할떄 주의할점
Stack 영역
변수할당시 생성
함수가 끝날때 삭제

참조가 한번 끊어지면 다시 heap영역의 data에 접근이 되지 안흔ㄴ다 -> heap영역의 과잉생산 -> 메모리 누수

데이터가 있지만 활용하지 못하는것 -> 쓰레기(가비지)
데이터가 언제 삭제되는지 모름, 단 한 조건은 있음
데이터가 사용되지 않을때 (참조가 끊겼을때)

GC가 언젠가 쓰지않는 데이터를 호출하여 처리해줌

가비지가 생긴다고 했을때
가비지를 1개만 가져가면 괜찮지만
가비지를 100개 1000개씩 한번에 가져갈때
컴퓨터가 과부하가 걸린다 -> 게임시 렉이 걸리는 이유

효율적으로 쓴다 = 가비지를 최대한 적게 생성시킨다.

Heap영역
new를 통해 생성 GC로 인해 삭제
Unity에서는 Instanitate() , Destroy()
하지만 Destroy()에서는 오브젝트가 삭제되는거지 Data는 남아있어 가비지로 남아있음 

유니티 inspector에 들어간 컴포넌트의 상위는 Class ->Monobehaviour 이다. 즉 ,  Instanitate() 를하면 new를 통해 생성하는것과 똑같은 의미이다.

최적화 -> 반복적으로 new 하는것을 줄인다
(Update,While 등등...)

최적화 1.
데이터를 한번 준비하고 **재활용**
-> 변수들을 미리 선언하여 호출하여 쓰기 

Unity에서 Vector는 구조체이기 때문
C/C++ 에서는 구조체나 class는 비슷하다.
(왜냐하면 프로그래머가 직접 메모리 할당 및 해지 , 포인터를 이용한 주소값 접근을  담당하기 때문)

하지만 C#은 다르다.
구조체는 데이터 자체가 Stack영역에 생성됨
즉, 구조체는 가비지가 남지 않게된다.
Stack 메모리가 heap 속도보다 더 빠르다
즉, Vector는 자주 사용되기 때문에 구조체로 Unity에서 만든것이다.

string str = "유저 레벨"

유 저  레 벨 이라는 5가지 저장됨

문자열은 불변객체 = 변하지 않는다는 뜻

str += "chad" 가 실행되면

내부적으로 간단하게
유저 레벨 뒤에 chad가 붙는것이 아니다.
즉, 유저 레벨 뒤 heap영역 메모리 데이터에 다른 데이터들도 있기에 붙일수가 없기 때문이다. 

유저레벨 + chad를 합친 문자열을 다른 heap영역에 새로 만들어진다. 

즉, heap에는 유저 레벨 , 유저레벨 chad 데이터가 2개가 동시에 존재하는 것이다
즉 string의 += 연산자를 계속 쓸때마다 heap영역을 쓰는 것이고 추가가 되어진다. 

이런 현상을 "파편화"라고 한다.

문자열 대처법
1.string을 한번에 제작 [ 보간문자열,스트링포맷,+연산자]
(추천)1-1.보간 문자열 : 문자열 앞에 $ 표시를 붙여 사용한다.
1-2.string.Format
1-3.+연산자를 한줄에 적어버리기

문자열을 한번에 제작하지 못하는경우
2.StringBuilder 사용하기

근데 왜 StringBuilder는 왜 이렇게 사용해도 괜찮은가??
ex)
유저 레벨 이 5글자이면 , StringBuilder는 추가로 공간을 확보해놓고 해당 확보한 공간을 넘어서는경우 새로 ㅏㄴ들게 된다. -> C#의 List와 유사하다.

stringBuilder는 처음에 16글자
넘어가면 2배인 32글자를 새로운 heap영역에 할당 이런식으로 된다.

stringBuilder는 일반 문자열보다 느리지만 파편화를 덜 방지 할 수 있기에 사용이 추천된다.

StringBuilder도 처음 초기화시 크기를 선언하고 사용 할 수 있다.

웬만한 문자열은 보간문자열을 사용할 수 ㅣㅆ고
중간중간 문자열이나 Data를 실시간으로 조합할때는 StringBuilder를 추천한다.
(개별 입력으로 받아들여서 합치는 경우에는 StringBuilder, 개발자가 처음 부터 값을 넣어주는 경우에는 $""를 쓰는 게 좋겠군요.)

Stack 값 형식 =  value
C#의 기본 타입(int,float,bool,char) , 구조체 , enum
Heap 참조형식 = referance
string class 배열 interface delegate

구조체는 Stack에 할당
메모리는 Stack에만 저장
큰 데이터나 외부 데이터를 가져와서 사용할떄 문제 발생

Calss는 Heap에 할당
Class의 객체(변수)는 stack에
Class 객체의 data는 heap영역에
데이터 접근은 Stack에 접근후 데이터의 주소를 파악후 heap영역에 접근한다. 

C#에서는 Class를 만들떄 new 어트리뷰트를 사용하여 생성한다. 유니티는 Instaiate는 new키워드와 유사한다

Static 키워드가 변수 ,메서드가 있으면
외부의 클래스의 이름을 바로 호출하여 바로 사용 할 수 있다.

Static을 메모리 관점으로 봤을때
Data영역에 배치 되어있음 
Data 영역은 프로그램 시작시 생성
프로그램 종료시 삭제

즉 , Static 키워드는 Data영역에 접근하여 언제든지 호출이 가능해진다.

Static 키워드 데이터는 Scene 사이의 데이터가 유지되어있다.

Static Class는 데이터를 세팅해줘야 됨
나머지 int,float은 언제든지 쓸 수 있음 
객체도 Class라서 초기값은 null이다.

Static 키워드들이 heap,stack영역 데이터에 접근해서 사용 할수는 없다.

'C#' 카테고리의 다른 글

Dirty Flag Pattern  (0) 2026.02.03
C# :: 메모리 구조  (0) 2024.10.14

+ Recent posts