프로세스 포크가 가상 또는 상주 메모리를 복사 할 때


12

Linux에서 새 프로세스를 작성하는 표준 방법은 상위 프로세스의 메모리 풋 프린트가 복사되어 execv호출 될 때까지 하위 프로세스의 환경이되는 것입니다 .

가상 (프로세스가 요청한 것) 또는 상주하는 메모리 (실제로 사용되는 것)에 대해 이야기하는 메모리 공간은 무엇입니까?

동기 부여 : 스왑 공간이 제한된 장치와 가상 메모리와 상주 메모리 공간이 크게 다른 응용 프로그램이 있습니다. 메모리 부족으로 인해 응용 프로그램을 포크 할 수 없으며 가상 풋 프린트 크기를 줄이려고하면 도움이되는지 확인하고 싶습니다.

답변:


12

현대 시스템에서는 포크 시스템 호출이 사용되어 메모리가 실제로 복사되지 않습니다. 처음에는 커널 코드에 트랩을 쓰려고 시도 할 수 있도록 페이지 테이블에서 모두 읽기 전용으로 표시됩니다. 첫 번째 프로세스에서 한 번만 쓰기를 시도하면 복사가 수행됩니다.

이것을 기록 중 복사라고합니다.

그러나 커밋 된 주소 공간을 추적해야 할 수도 있습니다. 커널이 페이지를 복사해야 할 때 사용 가능한 메모리 나 스왑이 없으면 메모리를 확보하기 위해 일부 프로세스를 종료해야합니다. 이것이 항상 바람직한 것은 아니므로 커널이 커밋 한 메모리 양을 추적 할 수 있습니다.

커널이 사용 가능한 메모리 + 스왑 이상을 커밋하는 경우 포크 호출시 오류 코드가 표시 될 수 있습니다. 충분한 양이 있다면 커널은 포크 후 두 프로세스 모두에 대해 부모의 전체 가상 크기를 커밋합니다.


1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.네 감사합니다. 메모리 (RAM 및 스왑)가 제한된 환경에서 프로세스의 가상 풋 프린트를 줄이면 분기 할 수없는 문제를 해결할 수 있습니다.
TheMeaningfulEngineer 2016 년

1
@Alan 예. fork메모리 부족을 나타내는 오류 메시지와 함께 실패하는 경우 . 그런 다음 분기 전에 프로세스의 가상 메모리 사용량을 줄이는 것이 도움이 될 수 있습니다.
kasperd 2016 년

5

걱정하지 마십시오. 게으른 사본 (기록 중 복사)이 만들어집니다. 두 프로세스의 가상 메모리 주소는 처음에 동일한 페이지를 가리 키지 만 분기 프로세스가이를 수정하려고 할 때 실제로 페이지의 실제 사본을 만듭니다 (그 이후부터 해당 페이지는 RAM의 두 위치에 있습니다).

보고 된 메모리 풋 프린트는 실제로 프로세스가 사용중인 RAM의 양을 알려주지 않습니다. 스와핑, 메모리 공유 및 가상 메모리의 다른 문제로 인해 확실하게 알 수 없습니다. 메모리 공간의 일부는 공유 라이브러리 (카운트 위치)? 일부는 비 RAM 메모리 (다른 하드웨어 장치)를 참조하고 일부는 현재 스왑 아웃되어 있으며 일부는 아직 복사되지 않았습니다 (복사시 복사). 곧. 이것을 읽으십시오 :

https://lwn.net/Articles/642202/


5

커널 설정이 있습니다

/ proc / sys / vm / overcommit_memory

우수 논문 인용 :

Since 2.5.30 the values are: 0 (default): as before: guess about how much  
overcommitment is reasonable, 1: never refuse any malloc(), 2: be precise 
about the overcommit - never commit a virtual address space larger than swap 
space plus a fraction overcommit_ratio of the physical memory. Here 
/proc/sys/vm/overcommit_ratio (by default 50) is another user-settable 
parameter. It is possible to set overcommit_ratio to values larger than 100. 
(See also Documentation/vm/overcommit-accounting.)

이것은 일반적인 malloc뿐만 아니라 포크에도 적용됩니다. 즉, 0으로 설정하면 포크는 쓰기시 복사됩니다. 쓰기시 복사는 앱이 포크되면 두 복사본이 모두 하위 또는 유틸리티가 메모리를 변경하기 시작하는 메모리 페이지를 공유 함을 의미합니다.

대부분의 배포판에서 overcommit은 0이라는 것을 알고 있습니다. 그러나 2로 설정하면 모든 메모리 페이지가 실제 메모리에 의해 완전히 백업되며 경우에 따라 높은 메모리 압력 하에서 더 안정적이지만 일부 프로그램은 gitk에 직면합니다. 초과 커밋에 실패합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.