개발자의시작

파이썬(python) 메모리 관리 1 본문

프로그램언어/python

파이썬(python) 메모리 관리 1

LNLP 2021. 4. 30. 02:50

파이썬의 메모리 관리는 대부분 Python Memory Manager에 의해 수행되지만 최상의 코딩 방법과 Python Memory Manager 작동 방식에 대한 이해는 보다 효율적이고 유지 관리 가능한 코드로 이어질 수 있습니다.

 

개발자를 위한 메모리 관리에서 가장 중요한 부분은 메모리 할당(memory allocation)입니다. 컴퓨터의 실제 또는 가상 메모리에 빈 공간 블록을 할당하는 프로세스를 이해하는 것이 중요합니다. 메모리 할당에는 두 가지 유형이 있습니다.

 

 

1. 정적 메모리 할당

- 프로그램 컴파일시 메모리가 할당됩니다. 이에 대한 예는 C/C++에 있으며 고정 크기로만 정적 배열을 선언합니다. 메모리는 컴파일할 때 할당되며, 스택은 정적 할당을 구현하는 데 사용됩니다. 이 경우 메모리를 재사용할 수 없습니다.

 

2. 동적 메모리 할당

- 프로그램 런타임시 메모리가 할당됩니다. 이에 대한 예는 C/C++에 있으며, new() 연산자를 사용하여 배열을 선언합니다. 메모리는 런타임에 할당되며, 힙은 동적 할당을 구현하는 데 사용됩니다. 이 경우 필요하지 않은 메모리를 비우고 재사용할 수 있습니다.

 

※파이썬의 메모리 관리

파이썬의 모든 것은 객체입니다. 이것은 동적 메모리 할당이 파이썬 메모리 관리의 기초라는 것을 의미합니다. 객체가 더 이상 필요하지 않으면 Python Memory Manager가 자동으로 객체에서 메모리를 회수합니다. 

 

C/C++ 또는 자바의 경우 malloc과 같은 함수를 이용해서 동적 할당을 사용할 수 있게 됩니다. 하지만, 파이썬은 동적 할당의 기능이 없습니다. 즉, 사용자가 직접 메모리 할당 범위를 조정하지 않습니다. 

 

그렇다면 파이썬은 스택 영역만 사용하는 언어인가, 그렇지 않습니다. 파이썬은 메모리를 관리해주는 특별한 기능이 있습니다. 바로 위에서 언급한 Python Memory Manager인데, 이 기능이 포이터를 움직여 힙 영역의 메모리 할당 범위와 내부 버퍼를 조정해줍니다. Python Memory Manager는 Python/C API를 통해 스토리지를 동적으로 관리합니다. 

 

※ Everything is object in Python

 

1. 핵심 개념

 

- C언어에서 x=10과 같이 변수를 할당하면 메모리에 해당 값이 바로 저장되지만, 파이썬에서는 10이라는 int object를 만들어 놓고 변수 x가 그것을 가리키는 형태이다. 그리고 y=x라고 하면 x에 의해서 이미 만들어진 10이라는 int object를 y는 그냥 가리키기만 한다. 그래서 x와 y는 같은 object를 가리킨다고 말한다.

 

- x=x+1은 11이라는 새로운 int object를 생성한다. 그리고 x는 새롭게 만들어진 int object를 가리킨다. 그리고 z=10이라는 int object를 가리키는데 10 int object는 이미 생성되었으니 만들 필요 없고 그냥 가리키기만 한다. 

 

2. 메모리 할당 (stack, heap)

 

 

- main 함수에서 y=5 (5 int object 생성 및 가리키기)와 f1(y) 함수를 call 한다. f1(y)를 호출하면 stack 영역에 f1() 영역이 생성된다. 

- f1 함수에서 x=x*2로 10 int object를 생성 및 가리키기를 하고 f2(x)를 호출하면 stack 영역에 f2() 영역이 생성된다.

- f2 함수에서 x=x+1로 11 int object를 생성 및 가리키기를 한다.

- 메소드와 변수는 스택 메모리(초록색 블록)에 작성된다. 이러한 프레임은 메소드가 리턴될 때마다 자동으로 제거된다.

 

3 메모리 할당 해제

 

 

- 우선 stack의 가장 위에 있는 f2함수가 해제된다.

- 그다음 f1함수가 해제되는데 f1 함수의 변수 x가 없어짐에 따라 10 int object도 없어진다( 10 int object를 아무도 가리키지 않기 때문). 이것이 바로 reference counting이 0이 됨에 따라 object가 없어지는 가비지 컬렉터이다. 파이썬은 레퍼런스 카운팅을 이용해 메모리를 관리한다. 원리는 f1함수가 해제될 때 10 int object가 사라지는 것이 대표적인 예이다.

- 마지막으로 main 함수의 변수 z는 11을 가리킨다.

 

4 Class instance 메모리 관리(self는 무엇인가)

 

 

(할당 해제)

- main에서 c=Car(4)는 class instance를 생성하는데 처음에 생성자 함수 __init__이 호출된다. 여기서 self, w 2개를 매개변수로 받는데, 이는 매개변수 즉 지역변수이기 때문에 stack 영역에 생성된다.

- w는 당연히 4인데, self는 무엇일까? 그림에서 보듯 Car instance(object)의 주소(reference) 값이다. 즉, 모든 class 메소드는 self를 매개변수로 가지는데 self는 자신의 Class instance의 주소 값이다. 너무나 중요한 말이고 너무나 당연한 말이다. self를 매개변수로 받지 않으면 어떻게 instance 값을 참조할 것인가?

- 그리고 self.wheels은 instance의 변수 즉 속성(attribute)이다. attribute는 heap 영역에 할당된다. 왜냐하면 __init__ 함수가 없어지고 stack 영역이 사라져도 self.wheels 는 항상 존재해야 하기 때문이다.( 생성자 메소드가 종료돼도 변수는 남아 있어야 한다.)

 

(메소드 실행)

 

- c.getWheels()를 실행하면 stack 영역이 만들어지고 매개변수로 self가 생성된다. self는 instance의 주소 값을 가지고 있는 변수이니 self를 통해 heap 영역의 wheels 변수에 접근한다. 접근 값은 4이고 main 함수의 n 값은 heap 영역의 4를 가리킨다. 

- 변수와 함수가 반환되자마자 죽은 개체는 가비지 수집된다.

Comments