프로그램이 일부 메모리를 요청했지만 사용 가능한 메모리가 충분하지 않다고 가정해 보겠습니다. Linux는 여러 가지 다른 방식으로 응답합니다. 한 가지 응답은 최근에 액세스되지 않은 다른 사용된 메모리를 선택하고 해당 비활성 메모리를 스왑 영역으로 이동하는 것입니다.
하지만 이를 넘어서는 글과 댓글을 많이 봅니다. 사용 가능한 메모리가 많더라도 Linux는 때때로 비활성 메모리를 스왑 영역에 쓰기로 결정한다고 말합니다. 미리 쓰기 스왑은 최종적으로 이 메모리를 사용하려고 할 때 디스크 쓰기를 기다릴 필요가 없음을 의미합니다. 성능을 최적화하기 위한 사려 깊은 전략이라고 하네요.
그 말이 맞나요? 아니면 이것은 신화인가? 출처를 인용하세요.
문제를 이해하려면 다음 정의를 사용하세요.
- 교환
- 무료메모리 - "사용 가능한" 메모리가 표시됩니다.무료주문하다.
MemFree
에서 가져온 값 입니다/proc/meminfo
./proc/meminfo
커널에서 제공하는 가상 텍스트 파일입니다. 바라보다공정(5), 또는RHEL 문서. - 사용 가능한 메모리가 많아도- 데모 목적으로 사용 가능한 메모리가 10% 이상이라고 가정합니다.
인용하다
다음은 몇 가지 검색어입니다.linux "기회적 스왑" OR ("시스템에 더 나은 할 일이 없을 때" 스왑 OR "더 나은 할 일이 없을 때" OR "시스템이 유휴 상태일 때" OR "유휴 시간 동안")
free
Google에서 두 번째로 높은 결과에서 StackExchange 사용자는 "RAM에 여유 공간이 충분한데 왜 스왑을 사용합니까?"라고 물었고, 약 20%의 여유 메모리를 보여주는 명령 결과를 복사했습니다. 이 특정 질문에 대한 답변에서 다음 답변이 높은 평가를 받았습니다.
Linux는 RAM이 가득 차기 전에 스왑을 시작합니다. 이는 성능과 응답성을 향상하기 위해 수행됩니다.
때로는 RAM이 프로그램 메모리 저장보다 디스크 캐시에 더 적합하기 때문에 성능이 향상됩니다. 따라서 한동안 사용하지 않은 프로그램은 교체하고, 자주 사용하는 파일은 캐시에 보관해 두는 것이 좋습니다.
메모리가 가득 차고 일부 프로그램이 실행 중일 때보다 시스템이 유휴 상태일 때 페이지를 교환하고 작업을 완료하기 위해 더 많은 RAM을 요청하면 응답성이 향상될 수 있습니다.
물론 스와핑으로 인해 시스템 속도가 느려지지만 스와핑의 대안은 스와핑이 아니라 더 많은 RAM을 사용하거나 더 적은 RAM을 사용하는 것입니다.
Google의 첫 번째 결과는 위 질문과 중복된 것으로 표시되었습니다. :-). 이 예에서는 Inquirer 사본의 세부 정보가 7GB MemFree
(총 16GB)로 표시됩니다. 이 질문에는 승인되고 찬성된 답변이 있습니다.
0으로 설정하면 사용 가능한 메모리가 없는 경우에만 스왑이 발생합니다.
swappiness
그렇지 않으면 유휴 기간 동안 커널이 메모리를 스왑합니다. 이 과정에서 데이터는 메모리에서 삭제되지 않지만 스왑 파티션에 복사본이 생성됩니다.즉, 메모리 부족 상황이 발생하면 즉시 디스크에 쓸 필요가 없습니다. 이 경우 커널은 데이터 복사본이 있다는 것을 알고 있기 때문에 교체된 메모리 페이지를 덮어쓸 수 있습니다.
이
swappiness
매개변수는 기본적으로 이 작업을 수행하는 정도를 제어합니다.
다른 참조에 의해 교체되어 명시적으로 선언되지 않은 데이터도 메모리에 남아 있습니다. 하지만 여유 메모리가 20%인 경우에도 스왑을 수행하는 경우 이 접근 방식을 선호하는 것으로 보이며 그렇게 하는 이유는 성능을 향상시키기 위한 것입니다.
내가 아는 한, Linux는 주 메모리와 스왑 공간에 동일한 데이터의 복사본을 보관하는 것을 지원합니다.
'자유시간'에 '기회주의적 교류'가 일어난다는 속담도 눈에 띈다. 나는 이 기능이 일반적으로 성능에 좋다는 것을 확신하는 데 도움이 될 것이라는 것을 알고 있습니다. 명확한 질문을 하기에 충분한 세부사항이 있다고 생각하기 때문에 위의 정의에 포함시키지 않았습니다. 나는 필요 이상으로 일을 더 복잡하게 만들고 싶지 않습니다.
초기 동기
사용 가능한 메모리가 기가바이트이면 상단에 "swout"이라고 표시됩니다. 왜?
사용 가능한 메모리가 충분할 때 Linux에서 스왑을 작성한다는 보고가 있습니다. "기회주의적 교환"이 이러한 보고서를 설명할 수 있습니다. 그 동안 적어도 하나의 대체 이유가 제안되었습니다. 가능한 원인을 찾는 첫 번째 단계: Linux가 위에 정의된 "기회적 스와핑"을 수행한 적이 있습니까?
제가 보고한 예에서는 이제 질문에 대한 답변이 제공되었습니다. 그 이유는 기회주의적 교환이 아니기 때문이다.
답변1
Linux는 이 질문에 정의된 "기회적 스와핑"을 수행하지 않습니다.
다음 주요 참고 자료에서는 이 개념을 전혀 언급하지 않습니다.
- Linux 가상 메모리 관리자 이해. Mel Gorman의 온라인 도서. Linux 2.6.0이 출시되기 전인 2003년에 작성되었습니다.
- 문서/AdminGuide/sysctl/vm.rst. 이는 Linux 가상 메모리 관리 조정 가능 설정에 대한 기본 문서입니다.
뿐만 아니라:
과거에는
kswapd
10초마다 깨어나곤 했지만 이제는 해당 영역의 사용 가능한 페이지 수가 page_low에 도달하면 물리적 페이지 할당자에 의해서만 깨어납니다. [...] 메모리 부족이 극심한 경우 프로세스는 작업을 동기식으로 완료합니다kswapd
. [...]kswapd
Pages_high 워터마크에 도달할 때까지 페이지를 계속 공개합니다.
위의 내용을 토대로 사용 가능한 페이지 수가 "하이 워터 마크"를 초과하면 스왑이 발생하지 않을 것으로 예상됩니다.
둘째, 이는 kswapd
더 많은 무료 페이지를 만드는 것이 목적임을 알려줍니다.
kswapd
메모리 페이지가 스왑 영역에 기록 되면 즉시 메모리 페이지가 해제됩니다.kswapd는 스왑 페이지의 복사본을 메모리에 보관하지 않습니다..
리눅스 2.6은 "매핑"페이지를 해제합니다. Linux 2.4에서는 상황이 더 복잡합니다. 페이지가 여러 프로세스에 의해 공유되면 kswapd가 이를 즉시 해제할 수 없습니다. 이것은 고대 역사입니다. 링크된 모든 게시물은 Linux 2.6 이상에 관한 것입니다.
이 컨트롤은 커널이 메모리 페이지를 얼마나 적극적으로 교환하는지 정의합니다. 값이 높을수록 공격성이 증가하고, 값이 낮을수록 교환량이 감소합니다. 0 값은 유휴 양에 도달할 때까지 커널이 스와핑을 시작하지 않도록 지시합니다.및 파일 지원 페이지해당 지역의 최고 수위점보다 낮습니다.
이 인용문은 특별한 경우를 설명합니다. swappiness
값이 로 구성된 경우 0
이 경우에는 교환이 발생하지 않아야 합니다.은닉처페이지가 최고 워터마크로 떨어졌습니다. 즉, 커널은 스왑을 시작하기 전에 거의 모든 파일 캐시를 버리려고 시도합니다. (이로 인해 속도가 크게 느려질 수 있습니다. 약간의 파일 캐싱이 필요합니다! 파일 캐시는 실행 중인 모든 프로그램의 코드를 저장하는 데 사용됩니다. :-)
워터마크란 무엇입니까?
위의 인용문은 다음과 같은 질문을 제기합니다.내 시스템의 "워터마크" 메모리 예약은 얼마나 됩니까?A: "소형" 시스템에서는 기본 영역 워터마크가 메모리의 3%까지 높을 수 있습니다. 이는 "최소" 워터마크 계산 때문입니다. 대규모 시스템에서는 워터마크가 메모리의 0.3%에 가까운 더 작은 비율을 차지합니다.
따라서 문제가 10% 이상의 여유 메모리가 있는 시스템과 관련된 경우 이 워터마크 논리의 특정 세부 사항은 중요하지 않습니다.
각 개별 "지역"에 대한 워터마크는 /proc/zoneinfo
다음과 같이 표시됩니다.공정(5). 내 구역 정보에서 발췌:
Node 0, zone DMA32
pages free 304988
min 7250
low 9062
high 10874
spanned 1044480
present 888973
managed 872457
protection: (0, 0, 4424, 4424, 4424)
...
Node 0, zone Normal
pages free 11977
min 9611
low 12013
high 14415
spanned 1173504
present 1173504
managed 1134236
protection: (0, 0, 0, 0, 0)
현재 "워터마크"는 min
, low
및 입니다 high
. 프로그램이 free
아래로 줄이기 위해 충분한 메모리를 필요로 하는 경우 min
프로그램은 "직접 재활용"으로 들어갑니다. 프로그램은 커널이 메모리를 해제하는 동안 기다립니다.
가능하다면 직접 재활용을 피하고 싶습니다. 따라서 워터마크 free
아래에 있으면 low
코어가 깨어납니다 kswapd
. 위의 상황이 다시 발생할 kswapd
때까지 캐시를 교체하거나 삭제하여 메모리를 확보하세요 .free
high
추가 자격: kswapd
커널 lowmem 및 DMA 사용을 위해 전체 lowmem_reserve 볼륨을 보호하기 위해 실행됩니다. 기본낮은 메모리 예약이는 RAM의 첫 번째 4GiB(DMA32 영역)의 약 1/256이므로 일반적으로 약 16MiB입니다.
리눅스 코드 제출
mm: 메모리 비율에 따라 kswapd 워터마크 크기 조정
[...]
워터마크 배율:
이 요소는 kswapd의 공격성을 제어합니다. 이는 kswapd가 깨어나기 전에 노드/시스템에 남아 있는 메모리 양과 kswapd가 다시 절전 모드로 전환되기 전에 해제해야 하는 메모리 양을 정의합니다.
단위는 10,000의 분수입니다. 기본값 10은 워터마크 사이의 거리가 노드/시스템에서 사용 가능한 메모리의 0.1%임을 의미합니다. 최대값은 1000이며 이는 메모리의 10%입니다.
직접 수집(allocstall)에 진입하거나 kswapd가 조기에 절전 모드로 전환(kswapd_low_wmark_hit_quickly)되는 스레드의 비율이 높다는 것은 대기 시간 이유로 kswapd에서 유지 관리하는 사용 가능한 페이지 수가 시스템에서 발생하는 할당 버스트에 비해 너무 작다는 것을 의미할 수 있습니다. 그런 다음 이 손잡이를 사용하여 kswapd의 공격성을 적절하게 조정할 수 있습니다.
proc: meminfo: 사용 가능한 메모리에 대한 보다 보수적인 추정
MemAvailable
의 항목은/proc/meminfo
스와핑을 유발하지 않고 얼마나 많은 메모리를 할당할 수 있는지 사용자에게 묻는 메시지를 표시하기 위한 것이므로 사용자 공간에서 사용할 수 없는 하위 워터마크 영역을 제외합니다.그러나 사용자 공간 할당의 경우
kswapd
사용자 공간에서 특정 양의 DMA 및 DMA32 메모리를 예약하는 페이지 할당자의 낮은 메모리 보호 조합을 통해 사용 가능한 페이지가 최고 워터마크에 도달할 때까지 실제로 재활용이 수행됩니다.MemAvailable을 계산할 때 사용 가능한 페이지 수에서 사용자 공간에서 사용할 수 없는 총 페이지 수를 뺍니다.
리눅스 코드
이를 변경하면 "기회적 교환"이 효과적으로 비활성화된다는 주장 swappiness
이 가끔 있습니다. 0
이는 흥미로운 조사 방법을 제공합니다. 소위 "기회적 교환"이 있고 교환 여부에 따라 조정될 수 있는 경우 모든 읽기의 호출 체인을 찾아 추적할 수 있습니다 vm_swappiness
. 설정되지 않았다고 가정하여 검색 공간을 줄일 수 있습니다 CONFIG_MEMCG
(즉, "메모리 cgroup"이 비활성화됨). 호출 체인은 다음과 같습니다.
shrink_node_memcg
"이것은 더 자유로운 기본 노드별 페이지입니다. kswapd 및 직접 재활용에서 사용됩니다."라고 설명되었습니다. 즉, 이 함수는무료페이지. 나중에 해제할 수 있도록 페이지를 교환하기 위해 복사하려고 시도하지 않습니다. 그러나 우리가 이것을 고려하지 않더라도:
위 체인은 아래와 같이 세 가지 다른 함수에서 호출됩니다. 예상대로 호출 사이트를 직접 재활용과 kswapd로 나눌 수 있습니다. 직접 재활용에서는 "기회주의적 교환"을 수행하는 것이 의미가 없습니다.
-
/* * 페이지 할당 과정을 위한 직접 회수 경로입니다. 우리밖에 없어 * 호출자의 할당을 만족하는 영역에서 페이지를 회수하려고 시도합니다. * 필요하다. * * 특정 영역이 고정된 페이지로 가득 찬 것으로 간주되는 경우 해당 영역에 표시기를 제공하세요. * 스캔 후 포기하세요. */ 정적 유효하지 않음수축 면적
-
* kswapd는 사용 가능한 최고 값과 같거나 낮은 페이지 노드를 축소합니다. * 현재 불균형 지역입니다. * * kswapd가 요청한 페이지 수 이상을 스캔한 경우 true를 반환합니다. * 재활용 또는 페이지 다시 쓰기로 인해 진행이 부족한 경우. * 검색 우선순위를 높여야 하는지 결정하는 데 사용됩니다. */ 정적 부울kswapd_shrink_node
-
* kswapd의 경우 Balance_pgdat()는 해당 지역의 노드 전체에서 페이지를 재활용합니다. * 발신자는 최소한 한 곳이 이용 가능해질 때까지 이 지역을 사용할 수 있습니다. * 균형. * * kswapd가 재활용을 완료하는 순서를 반환합니다. * * kswapd는 highmem->normal->dma 방향으로 영역을 스캔합니다. 건너뛸 거예요 * free_pages > high_wmark_pages(zone)인 영역, 그러나 한 번 영역 * free_pages <= high_wmark_pages(zone) 발견, 이 영역의 모든 페이지 * 이하의 경우 무료 구역이 하나 이상 매립될 때까지 매립 대상이 됩니다. * 균형. */ 정적 정수Balance_pgdat
따라서 일반적인 이론은 모든 메모리 할당이 사용 가능한 메모리에서 즉시 충족되더라도 kswapd가 어떤 방식으로든 깨어난다는 것입니다. 나는 사용법을 보았고 wake_up_interruptible(&pgdat->kswapd_wait)
그러한 각성을 보지 못했습니다.
답변2
아니요, Linux에는 기회주의적 교환과 같은 것이 없습니다. 나는 이 문제를 연구하는 데 시간을 보냈고 모든 소스(교과서, 커널 개발자 메일링 리스트의 이메일, Linux 소스 코드 및 커밋 댓글, Mel Gorman과의 일부 Twitter 교환)에서 동일한 내용을 알려줍니다. Linux 전용 메모리 재활용 어떤 형태의 기억 스트레스에 대한 반응입니다(명백한 최대 절전 모드 제외).
이 주제에 대한 모든 대중적인 오해는 아마도 하나의 간단한 사실에서 비롯될 것입니다. Linux는 스와핑을 시작하기 전에 여유 메모리의 마지막 바이트까지 기다릴 수 없습니다. 극단적인 형태의 메모리 고갈로부터 보호하려면 일종의 버퍼링이 필요하며 해당 버퍼의 크기에 영향을 줄 수 있는 몇 가지 조정 가능한 매개변수가 있습니다(예: vm.min_free_kbytes
). 하지만 그것은 "더 이상 할 일이 없기 때문에 교환한다"는 것과는 다릅니다.
불행하게도 페이지 프레임 회수 알고리즘은 2.6 이후로 더 복잡해졌지만(Mel Gorman의 책에 자세히 설명되어 있습니다) 기본 아이디어는 거의 동일합니다. 페이지 회수는 실패한 할당에 의해 트리거된 다음 깨어나 kswapd
거나 메모리 부족, 할당 플래그 및 기타 요인에 따라 페이지를 동기적으로 해제합니다.
충분한 여유 메모리가 남아 있는 상태에서 페이지 할당이 실패하기 시작하는 가장 확실한 이유는 연속적인 메모리가 필요할 수 있다는 것입니다. 실제로는 요청을 충족하기에는 메모리가 너무 조각화되어 있을 수 있습니다. 역사적으로 Linux 커널 개발자는 지속적인 할당의 필요성을 피하기 위해 많은 노력을 기울였습니다. 그럼에도 불구하고 일부 장치 드라이버는 여전히 이 작업을 수행해야 합니다. 다중 페이지 메모리 I/O(분산 수집 DMA)를 수행할 수 없거나 드라이버 개발자 측의 코딩이 엉성할 수 있기 때문입니다. THP(투명 거대 페이지)의 출현은 물리적으로 인접한 블록에 메모리를 할당해야 하는 또 다른 이유를 제공합니다.
같은 시기에 도입된 영역 압축은 메모리 조각화 문제를 해결하는 데 도움이 될 것으로 예상되었지만 항상 원하는 효과를 얻지는 못했습니다.
특정 상황에서 정확히 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 수 있는 다양한 추적점이 있습니다 vmscan
. 특정 호출 스택이 있는 경우 원격으로 관련이 있어 보이는 것을 스캔하는 것보다 Linux 커널 코드에서 필요한 것을 항상 더 쉽게 찾을 수 있습니다. .