Linux가 기본적으로 메모리를 오버커밋하는 이유는 무엇입니까?

Linux가 기본적으로 메모리를 오버커밋하는 이유는 무엇입니까?

슈퍼유저 문제 관련https://superuser.com/questions/200387/linux-overcommit-memory내 질문은 그들이 기본값을 남용하는 것을 허용하는 이유가 무엇입니까?

2.5.30 기준으로 이 값은 다음과 같습니다. 0(기본값): 이전과 동일: 초과 구독이 얼마나 합리적인지 추측하고,

답변1

Linux(및 일반적인 Unix 시스템)에서 메모리 오버커밋에 대한 필요성의 대부분은 fork()호출 프로세스의 주소 공간을 복사하는 시스템 호출을 구현해야 하기 때문에 발생합니다.

대부분의 경우 이 시스템 호출 뒤에는 exec()두 가지가 결합되어 현재 프로세스의 하위 프로그램으로 별도의 프로그램이 생성되며, 이 경우 중복 주소 공간의 대부분은 사용되지 않습니다.

효율성을 높이기 위해 Linux는 쓰기 중 복사를 사용하여 호출 애플리케이션의 메모리 복사를 방지합니다 fork(). 이 경우 모든 페이지 복사를 방지하고 exec()호출 직후 해당 페이지를 삭제합니다.

하지만 호출을 하면 fork()누군가 오는지 알 수 없습니다 exec(). 이는 자식 프로세스를 생성하는 데 사용될 가능성이 높으며 부모의 주소 공간을 재사용하는 것이 바로 우리가 원하는 것입니다. (이 기술은 연결을 처리하기 위해 미리 포크된 작업자 프로세스를 사용하는 데몬에서 매우 널리 사용됩니다.) 이 경우 포크된 자식 프로세스는 메모리 요구 사항의 대부분 또는 적어도 일부를 갖게 됩니다(부모 프로세스 메모리의 100%는 아닐 수도 있음). , 그러나 대부분은 가정할 수 있습니다.)

fork()그러나 이 경우를 위해 항상 메모리를 예약하는 것은 + 상황에서 문제가 됩니다 exec(). 특히 상위 프로세스가 여러 GB의 메모리를 예약하고 많은 하위 프로세스를 포크하는 장기 실행 프로세스인 경우 더욱 그렇습니다. 과잉 커밋이 아닌 경우 상위 항목과 분기된 각 하위 항목이 사용하는 총 용량을 유지해야 합니다. 그러나 exec()예약이 즉시 플러시되므로 이들 중 어느 것도 실제로 사용되지 않습니다. 결과적으로 이러한 워크로드에는 많은 스왑 공간(대부분 예약을 처리하기 위해 사용되지 않지만 최악의 경우에는 있어야 함) 또는 과잉 커밋과 같은 것이 필요합니다.

이 예에서는 요점을 잘 설명 하지만 fork()Linux/Unix의 다른 API도 과도하게 사용할 필요가 있습니다. 예를 들어, malloc()호출될 때(더 정확하게는 이를 구현하는 시스템 호출) 메모리는 프로세스에 의해 "터치"될 때까지 실제로 할당되지 않으므로 매우 큰 기가바이트 블록이 할당되어 드물게 사용됩니다. 실제로는 몇 메가바이트가 사용됩니다. 이러한 API가 이러한 방식으로 작동한다는 사실은 프로그램이 이러한 속성을 활용한다는 것을 의미하며, 이는 초과 커밋 없이 충돌이 발생할 가능성이 있음을 의미합니다(이러한 예약을 지원하여 실제로 많은 메모리가 있거나 스왑 공간을 낭비하지 않는 한).

이 문제에 대한 흥미로운 토론은 fork()다음에서 찾을 수 있습니다.LWN에서 발행한 Microsoft Research 관련 기사. 물론 기사 자체는 흥미롭습니다. 그러나 이러한 댓글이 어떻게 즉시 남용과 그에 따른 문제로 이어질 수 있는지 알 수 있습니다.

기사 제목은갈림길 ().

답변2

그 이유는 모든 사람이 메모리를 구입할 만큼 리소스가 충분하지 않기 때문이라고 생각합니다. 따라서 이 경우 모든 애플리케이션이 제대로 실행되어야 하며, 이는 적은 리소스로 애플리케이션을 실행하는 데 도움이 됩니다.

관련 정보