2013-09-01 1 views
1

많은 리소그래피 계산을 수행 할 프로세스가 있으므로 메모리 풀에 메모리를 할당하기 위해 mmap을 사용했습니다. 프로세스가 큰 메모리 덩어리를 필요로 할 때 나는 덩어리를 할당하기 위해 mmap을 사용했다. 사용 후 덩어리를 메모리 풀에 넣었다. 동일한 청크 메모리가 프로세스에서 다시 필요하면 풀에서 직접 가져온다. 메모리는 사용하지 않는다. 다시 매핑하십시오 (필요한 메모리를 모두 할당하지 않고 프로세스 초기에 풀에 넣으십시오). mmaps 함수 사이에는 malloc()이나 new()와 같이 mmap을 사용하지 않는 메모리 malloc가 있습니다.memset 함수가 가상 메모리를 너무 크게 만드는 이유

질문 : 메모리 풀에 넣기 전에 memset()을 사용하여 모든 청크 데이터를 ZERO로 설정하면 프로세스가 다음과 같이 너무 많은 가상 메모리를 사용합니다. 형식은 "mmap (크기) = 가상 주소 "

mmap(4198400)=0x2aaab4007000 
mmap(4198400)=0x2aaab940c000 
mmap(8392704)=0x2aaabd80f000 
mmap(8392704)=0x2aaad6883000 
mmap(67112960)=0x2aaad7084000 
mmap(8392704)=0x2aaadb085000 
mmap(2101248)=0x2aaadb886000 
mmap(8392704)=0x2aaadba89000 
mmap(67112960)=0x2aaadc28a000 
mmap(2101248)=0x2aaae028b000 
mmap(2101248)=0x2aaae0c8d000 
mmap(2101248)=0x2aaae0e8e000 
mmap(8392704)=0x2aaae108f000 
mmap(8392704)=0x2aaae1890000 
mmap(4198400)=0x2aaae2091000 
mmap(4198400)=0x2aaae6494000 
mmap(8392704)=0x2aaaea897000 
mmap(8392704)=0x2aaaeb098000 
mmap(2101248)=0x2aaaeb899000 
mmap(8392704)=0x2aaaeba9a000 
mmap(2101248)=0x2aaaeca9c000 
mmap(8392704)=0x2aaaec29b000 
mmap(8392704)=0x2aaaecc9d000 
mmap(2101248)=0x2aaaed49e000 
mmap(8392704)=0x2aaafd6a7000 
mmap(2101248)=0x2aacc5f8c000 

마지막의 mmap - 첫번째 = 0x2aacc5f8c000 - 0x2aaab4007000 = 8.28G

하지만 내가 전에 메모리 풀에 넣어 memset 함수를 호출하지 않는 경우 :

,536,913 63,210
mmap(4198400)=0x2aaab4007000 
mmap(8392704)=0x2aaab940c000 
mmap(8392704)=0x2aaad2480000 
mmap(67112960)=0x2aaad2c81000 
mmap(2101248)=0x2aaad6c82000 
mmap(4198400)=0x2aaad6e83000 
mmap(8392704)=0x2aaadb288000 
mmap(8392704)=0x2aaadba89000 
mmap(67112960)=0x2aaadc28a000 
mmap(2101248)=0x2aaae0a8c000 
mmap(2101248)=0x2aaae0c8d000 
mmap(2101248)=0x2aaae0e8e000 
mmap(8392704)=0x2aaae1890000 
mmap(8392704)=0x2aaae108f000 
mmap(4198400)=0x2aaae2091000 
mmap(4198400)=0x2aaae6494000 
mmap(8392704)=0x2aaaea897000 
mmap(8392704)=0x2aaaeb098000 
mmap(2101248)=0x2aaaeb899000 
mmap(8392704)=0x2aaaeba9a000 
mmap(2101248)=0x2aaaec29b000 
mmap(8392704)=0x2aaaec49c000 
mmap(8392704)=0x2aaaecc9d000 
mmap(2101248)=0x2aaaed49e000 

의 mmap 마지막 - 첫번째 = 0x2aaaed49e000 - 0x2aaab4007000 = 916M

그래서 첫 번째 공정하고 살해 "메모리 부족".

프로세스에서 mmap 메모리 덩어리는 할당되었지만 사용되지 않거나 사용되지 않습니다. 예를 들어 교정 전에 프로세스 mmap 67112960 (64M)이 사용되지 않습니다 (쓰기 또는 이 메모리 영역에서 데이터를 읽음) 또는 처음 2M 바이트 만 사용한 다음 메모리 풀에 넣습니다.

나는 물리적 주소를 사용하는 실제 메모리가 지연 할당을 사용하여 mmap을 알고,이 주소에서 읽거나 쓸 때 할당됩니다.

하지만 혼란 스러웠던 점은 왜 가상 주소가 그렇게 많이 늘어나는 것입니까? 나는 centos 5.3을 사용했고, 커널 버전은 2.6.18이었고, libhoard와 GLIBC (ptmalloc) 모두에서이 과정을 시도했다.

누가 전에 동일한 문제를 해결합니까? 가능한 근본 원인은 무엇입니까?

감사합니다.

답변

1

VMA (가상 메모리 영역, AKA 메모리 매핑)가 연속적 일 필요는 없습니다. 첫 번째 예제는 ~ 256 Mb, 두 번째 ~ 246 Mb를 사용합니다.

공통 malloc() 구현은 mmap()을 큰 할당 (일반적으로 64KB 이상)에 사용하여 munmap()으로 해당 청크를 해제합니다. 따라서 큰 할당을 위해 수동으로 mmap()을 필요로하지 않으므로 malloc() 라이브러리가이를 처리 할 것입니다.

mmap() 인 경우 커널은 특수 0 페이지의 COW 복사본을 반환하므로 쓰기 전까지는 메모리를 할당하지 않습니다. 당신의 zeroing은 정말로 할당 된 메모리를 일으키고, 그것을 allocator에게 돌려 주며, 필요할 때 새로운 메모리 chunk를 요구한다.

결론 : 시스템이 사용자의 요구에 부적합하다는 것을 입증하지 않는 한 자신의 메모리 관리를 작성하지 말고, 실생활 부하로 사용자의 요구에 비해 눈에 띄게 나은 것으로 입증 된 경우에만 자신의 메모리 관리를 사용하십시오.

+0

프로세스가 동일한 alloc의 수천을 수행하므로 메모리 풀을 사용하므로 많은 시간을 절약 할 수 있습니다. 왜냐하면 mmap이 실제 메모리 할당을 수행하지는 않지만 실제로는 각 할당에 너무 많은 시간을 소비하기 때문입니다 . – Chaoxin