중화사전망 - 서예자전 - 파이썬이 값 기반 메모리 관리 모델을 채택한 이유는 무엇입니까?

파이썬이 값 기반 메모리 관리 모델을 채택한 이유는 무엇입니까?

얕은 수준에서 Python 의 메모리 관리 메커니즘은 세 가지 측면에서 설명할 수 있습니다.

(1) 가비지 수집

⑵ 참조 개수

(3) 메모리 풀 메커니즘

첫째, 가비지 수집:

C++, Java 등의 언어와 달리 파이썬은 변수 유형을 미리 선언하지 않고 변수에 직접 값을 지정할 수 있습니다. 파이썬의 경우, 객체의 유형과 메모리는

런타임에 결정됩니다. 그렇기 때문에 Python 을 동적 유형이라고 합니다. 여기서 동적 유형을 변수의 메모리 주소 할당으로 간단히 요약하면 런타임 시 변수를 자동으로 판단할 수 있습니다.

변수를 입력하고 값을 지정합니다.).

둘째, 참조 개수:

파이썬은 Windows 커널 객체와 비슷한 방식으로 메모리를 관리합니다. 각 객체는 객체에 대한 참조 개수를 유지합니다. 그림과 같이 (그림은 파이썬 코어 프로그래밍에서 가져온 것입니다)

X = 3. 14

Y = x

먼저 객체 3. 14 를 만든 다음 이 부동 소수점 객체에 대한 참조를 x 에 지정하겠습니다. x 가 첫 번째 참조이므로 이 부동 소수점 객체에 대한 참조 수는 1 입니다. 보고서 y =

X 는 동일한 객체를 가리키는 참조 별칭 y 를 작성합니다. Y 에 대한 새 객체를 만드는 것이 아니라 y 가 x 를 가리키는 부동 소수점 객체를 참조 개수가 2 인 것으로 나타났습니다.

우리는 위의 견해를 쉽게 증명할 수 있습니다.

변수 A 와 변수 B 의 id 는 동일합니다. id 값은 C 의 변수에 대한 포인터로 간주할 수 있습니다.

이 문제를 설명하기 위해 다른 웹 사이트의 그림을 참조합니다. C 언어의 경우 변수 A 를 만들 때 해당 변수에 대한 메모리 공간을 요청하고 변수 값을 변경합니다.

변수가 다른 변수 B 에 할당되면 B 에 대한 새 메모리 공간을 요청하고 변수 값을 B 의 메모리 공간에 배치합니다. 이것이 A 와 B 의 포인터가 일치하지 않는 이유입니다. 그림과 같이:

반면에 파이썬은 다릅니다. 사실 파이썬은 자바스크립트와 비슷합니다. 그림과 같이 변수는 객체에 부착된 레이블 (및 참조) 과 더 비슷합니다

유사한 정의). 변수가 객체에 바인딩될 때 변수의 참조 수가 1 (변수의 참조 수가 증가하는 다른 경우도 있음) 이면 해당 레이블이 자동으로 유지되고 결정됩니다.

레이블의 참조 수가 0 이 되면 쌍이 재활용됩니다.

셋째, 메모리 풀 메커니즘

파이썬의 메모리 메커니즘은 피라미드 행,-1 및 -2 층에서 작동하며, 이 세 계층은 주로 운영 체제에서 작동합니다.

레이어 0 은 C 의 malloc, free 등의 메모리 할당 및 해제 함수에 의해 작동합니다.

1 레이어 2 는 파이썬 인터페이스 함수인 PyMem_Malloc 에 의해 구현된 메모리 풀입니다. 오브젝트가 256K 보다 작으면 레이어에서 메모리를 직접 할당할 수 있습니다.

세 번째 레이어는 Python 객체에 대한 직접적인 조작인 최상위 레벨입니다.

C 에서 malloc 과 free 를 자주 호출하면 성능 문제가 발생합니다. 또한 작은 메모리 블록을 자주 할당하고 해제하면 메모리 조각화가 발생할 수 있습니다. 파이썬 (Python) 의 주요 작업은 다음과 같습니다.

요청 할당 메모리가 1~256 바이트 사이인 경우 자체 메모리 관리 시스템을 사용합니다. 그렇지 않으면 malloc 를 직접 사용합니다.

여전히 Malloc 를 호출하여 메모리를 할당하지만 한 번에 256k 크기의 큰 메모리 블록을 할당합니다.

메모리 풀에 등록된 메모리는 결국 메모리 풀로 회수되고 C 의 free 는 호출되지 않습니다.

다음에 사용할 수 있도록 풀어 주세요. 숫자 및 문자열과 같은 간단한 파이썬 객체의 경우 튜플을 복사합니다 (튜플은 변경이 허용되지 않음) (깊이 복사? ), 즉 다른 경우

변수 B 가 변수 A 에 할당되면 A 와 B 의 메모리 공간은 여전히 동일하지만 A 의 값이 변경되면 공간이 A 에 재할당되고 A 와 B 의 주소는 더 이상 동일하지 않습니다.

사전, 목록 등에 사용됩니다. , 하나를 변경하면 또 다른 변경 사항이 발생합니다. 이를 얕은 복제라고도 합니다.

부록:

참조 개수 증가

1. 만든 오브젝트: x=4

2. 기타가 생성됨: y = x.

3. 함수에 인수로 전달: foo(x)

4. 컨테이너 오브젝트의 한 요소인 a = [1,x,' 33']

참조 개수 감소

1. 로컬 참조가 범위를 벗어납니다. 예를 들어 위의 foo(x) 함수 끝에서 x 가 가리키는 객체 참조는 음수 1 입니다.

개체의 별칭이 명시 적으로 삭제됩니다. del x;; 또는 del y

3. 한 객체의 별칭이 다른 객체에 할당됩니다. x=789.

4. 오브젝트가 창 오브젝트에서 제거됩니다. my list. remove(x)

5. 창 개체 자체가 손상됨: del myList 또는 창 개체 자체가 범위를 벗어났습니다.

쓰레기 수거

1. 메모리에 사용되지 않는 부분이 있을 때 가비지 수집기에서 이를 정리합니다. 참조 수가 0 인 객체를 검사한 다음 메모리에서 해당 공간을 지웁니다. 물론 참조 수가 0 인 것 외에도 가비지 수집기에 의해 지워집니다. 두 객체가 서로 참조할 때 다른 참조는 이미 0 입니다.

2. 가비지 수집 메커니즘에는 순환 가비지 수집기도 있어 순환 참조 객체의 해제를 보장합니다 (A 는 B 를 참조하고 B 는 A 를 참조하므로 참조 개수는 0 이 아닙니다).