Languages/RUST

[Rust] 소유권 - 메모리 관리 이야기 (feat. Garbage Collector)

MOONCO 2023. 7. 14. 18:25

서문

 

Rust에는 소유권이라는 개념이 있는데,

이는 Rust에만 존재하는 고유한 특성이다.

이 글에서는 소유권이란 것이 무엇인지 뿐만아니라,

어떤 상황에서 사용하는지, 왜 등장하게 되었는지 등

자세한 내용을 알아보겠다.

 

소유권이란?

메모리 공간을 OS에게 반납(drop)할 수 있는 권한

 

 

등장 배경

프로그램을 사용하다보면, 특정 메모리공간을 공유하는 일이 많다 => 왜?

엄청난 크기의 데이터를 복사하는 경우를 생각해보면,

데이터 자체를 통째로 복사하기 보다, ( deep copy 깊은 복사 )

그 데이터가 저장된 주소를 대신 복사하는 방식이, ( shallow copy 얕은 복사 )

메모리 공간을 절약하는데 도움이 된다.

집사지말고, 쉐어하우스 ㄱㄱ

또한, 메모리를 다 사용하고 나면

OS가 사용할 수 있도록 돌려주어야지

다른 프로그램이 메모리를 사용할 수 있도록 할 수 있다.

 

이때 발생하는 문제점

 

1. 메모리 안돌려주는 경우

- 메모리 낭비 (memory leak)

 

2. 이미 돌려준 메모리를, 다시 돌려주려고 하는 경우

- 전력 낭비, 버그

 

3. 메모리를 너무 일찍 돌려주는 경우

같은 메모리를 주소를 참조 (포인트) 하고 있던 경우,

한쪽에서 메모리를 해제해버림 ( 아 난 다 씀 ~~ )

OS 님, 이제 집 빕니다~

 

반대쪽 : 이제 좀 써볼까?

=> 메모리 공간을 이미 OS에게 돌려주었으므로, 다른 프로그램이 사용하고 있을 수 있음

내 공간 아님 => 에러 발생

( 참고 - 이미 해제된 메모리 주소를 저장하고 있는 변수를, dangling pointer 라고 부른다 )

나가

 

여기서 알 수 있는, 같은 메모리 주소를 참조할 때 주의 해야 할점

메모리 공간을 OS에게 다시 돌려주고 싶다면,

그 전에, 공간을 참조하고 있는 변수들이 모든 작업을 마쳐야만 함.

 

해결방법

 Garbage Collector ( 쓰레기 차 )

사용이 끝난 메모리를 감시해서, 이를 OS에게 돌려주는 역할을 하는 것

 

소유권도, 이 문제를 해결하기 위해 등장한 프로그램

Garbage Collector == 쓰레기 모아서 처리하기

소유권 == 쓰레기 줄여서 버리기

 

차이점?

Garbage Collector 

- 여러개의 변수가, 하나의 메모리를 참조할 수 있음

- 하나의 메모리는, 여러개의 변수에 의해서 참조 될 수 있음

=> 데이터를 공유함

=> 데이터를 독점하지 않음 ( 참조한 누구나 변경가능 )

 

소유권

- 오직 하나의 변수가, 하나의 메모리를 참조하고 있음

- 하나의 메모리는, 오직 한개의 변수에 의해서 참조 될 수 있음

=> 데이터를 공유하지 않음

=> 데이터를 독점함 ( 소유권 )

=> 다른 변수가, 데이터를 사용하고자 한다면, 소유권을 넘겨 받아야 한다

 

소유권을 다른 변수로 옮기는 작업을 move 라고 부르고, (이동하니깐)

이때, 이전 주인은 메모리에서 삭제하여, 더 이상 접근할 수 없도록 만든다.

 

이렇게 되면, 결국 소유권을 가진 변수만, 해당 값에 접근 할 수가 있으므로

위의 문제점을 완벽히 해결할 수 가 있다.

또한, Garbage Collector 와 다르게, 별다른 감시 기능이 필요없으므로

더 효율적이다.

 

마무리

Rust는 이런 소유권 방식을 기본으로 사용하므로

데이터 "복사" 하는 경우, 데이터 자체를 복사되지 않는다.

이는 기본적으로 메모리를 효율적으로 관리하면서도

기존의 C언어를 사용하며 자주 실수하는

메모리 낭비 (leak) 문제나,

일부 dangling pointer 문제를 해결한다. ("일부")

 

하지만 그렇다고 해서, 자체 복사를 할 수 없는 것은 아니다.

Rust는 이런 부분을 "강제"하지 않고,

"기본"으로 사용함으로써

필요한 경우에 사용할 수 있는 자유도를 준다.

 

참고

소유권 은, "일부" dangling pointer 문제만을 해결하는데,

이는 소유권을 사용하지 않는 변수도 허용하고 있기 때문이다 (바로 위에 봤듯이)

 

이 때문에, 소유권을 사용하지 않는 변수도,

컴파일러가 검사할 수 있도록하는 개념이 필요했고

lifetime 개념이 등장하게된다. (수명)

 
 
 

 

 
 
 

 

 

 

반응형