2010-06-01 2 views
4

작은 프로그램을 작성하여 Solaris/Linux 플랫폼에서 컴파일하여이 코드를 애플리케이션에 적용 할 때의 성능을 측정했습니다.솔라리스/리눅스에서 할당 된 메모리 해제하기

프로그램은 처음에 sbrk(0) 시스템 호출을 사용하여 힙 영역의 기본 주소를 가져 왔습니다. 그 후에 나는 malloc 시스템 호출을 사용하여 1.5GB의 메모리를 할당했다. 그런 다음 memcpy 시스템 호출을 사용하여 1.5GB의 내용을 할당 된 메모리 영역에 복사했습니다. 그런 다음 할당 된 메모리를 해제했습니다.

해제 후, sbrk(0) 시스템 호출을 다시 사용하여 힙 크기를 봅니다.

여기 제가 약간 혼란 스럽습니다. 솔라리스에서는 할당 된 메모리 (약 1.5GB)를 확보했지만 프로세스의 힙 크기는 엄청납니다. 하지만 리눅스에서 같은 응용 프로그램을 실행 한 후 free 결과, 프로세스의 힙 크기가 1.5GB 할당 전에 힙 메모리의 크기와 같음을 발견했습니다.

솔라리스가 즉시 메모리를 비우지는 못하지만, free() 시스템 호출 후에 즉시 메모리를 확보하도록 Solaris 커널을 조정하는 방법을 모르겠습니다.

Linux에서 같은 문제가 발생하지 않는 이유는 무엇입니까?

답변

3

나는 물어 본 질문에 대한 답을 얻었다.

응용 프로그램 메모리 할당 자 :

C 및 C++ 개발자들은 수동으로 메모리 할당 및 해제를 관리해야합니다. 기본 메모리 할당자는 libc 라이브러리에 있습니다.

Libc free()가 실행 된 후에는 해제 된 공간이 응용 프로그램에서 추가 할당을 위해 사용할 수 있으며 시스템에 반환되지 않습니다. 메모리는 응용 프로그램이 종료 될 때만 시스템에 리턴됩니다. 이것이 애플리케이션의 프로세스 크기가 대개 감소하지 않는 이유입니다. 그러나 오래 실행되는 응용 프로그램의 경우 응용 프로그램 프로세스 크기는 일반적으로 해제 된 메모리를 다시 사용할 수 있기 때문에 안정된 상태로 유지됩니다. 그렇지 않은 경우 응용 프로그램이 메모리를 유출하고있는 것입니다. 할당 된 메모리는 사용되지만 더 이상 사용되지 않고 할당 된 메모리에 대한 포인터가 응용 프로그램에서 추적되지 않으면 기본적으로 손실됩니다.

libc의 기본 메모리 할당자는 특히 다중 스레드 C++ 응용 프로그램의 경우 동시 malloc 또는 빈 작업이 빈번하게 발생하는 경우 다중 스레드 응용 프로그램에 적합하지 않습니다. 이는 C++ 객체를 생성하고 파기하는 것이 C++ 응용 프로그램 개발 스타일의 일부이기 때문입니다. 기본 libc 할당자가 사용될 때 힙은 단일 힙 - 잠금에 의해 보호되어 malloc 또는 자유 동작 중에 과중한 잠금 경합 때문에 다중 스레드 응용 프로그램에 대해 기본 할당자가 확장 가능하지 않게됩니다. 다음과 같이 Solaris 도구로이 문제점을 쉽게 감지 할 수 있습니다.

먼저 응용 프로그램이 잠금에 많은 시간을 소비하는지 확인하려면 prstat -mL -p를 사용하십시오. LCK 열을보십시오. 예 :

-bash-3.2# prstat -mL -p 14052 
    PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID 
14052 root  0.6 0.7 0.0 0.0 0.0 35 0.0 64 245 13 841 0 test_vector_/721 
14052 root  1.0 0.0 0.0 0.0 0.0 35 0.0 64 287 5 731 0 test_vector_/941 
14052 root  1.0 0.0 0.0 0.0 0.0 35 0.0 64 298 3 680 0 test_vector_/181 
14052 root  1.0 0.1 0.0 0.0 0.0 35 0.0 64 298 3 1K 0 test_vector_/549 
.... 

이는 응용 프로그램이 잠금 대기 중 약 35 %를 소비하고 있음을 나타냅니다.

그런 다음 plockstat (1M) 도구를 사용하여 응용 프로그램이 대기중인 항목을 찾으십시오. 예를 들어, 프로세스 ID 14052로 5 초 동안 응용 프로그램을 추적 한 다음 C++ 심볼 이름을 분리하기 위해 C++ filt 유틸리티로 출력을 필터링하십시오. (C++ filt 유틸리티는 Sun Studio 소프트웨어와 함께 제공됩니다.) 응용 프로그램이 C++ 응용 프로그램이 아닌 경우 C++ filt를 통한 필터링은 필요하지 않습니다. 이전부터

-bash-3.2# plockstat -e 5 -p 14052 | c++filt 
Mutex block 
Count  nsec Lock       Caller 
------------------------------------------------------------------------------- 
9678 166540561 libc.so.1‘libc_malloc_lock libCrun.so.1‘void operator 
delete(void*)+0x26 

5530 197179848 libc.so.1‘libc_malloc_lock libCrun.so.1‘void*operator 
new(unsigned)+0x38 

...... 

, 당신은 힙 잠금 libc_malloc_lock이 심하게 경합하고 있고 확장 문제에 대한 원인입니다 것을 볼 수 있습니다. libc 할당 자의 이러한 스케일링 문제에 대한 해결책은 libumem 라이브러리와 같은 향상된 메모리 할당자를 사용하는 것입니다.

또한 방문 : 내 질문에, Santhosh에 대답하려고하는 모든 사람에 대한 http://developers.sun.com/solaris/articles/solaris_memory.html

감사합니다.