레이블이 memory인 게시물을 표시합니다. 모든 게시물 표시
레이블이 memory인 게시물을 표시합니다. 모든 게시물 표시

Linux free 명령으로 가용메모리 볼때 유의사항

[용도에 따른 메모리 영역]
wired 는 시스템이 필요로 하는 메모리로 스왑이나 캐시되지 않고 항상 메모리에 상주하고 있어야 한다.
shared 는 1개 이상의 프로세스가 공유하는 메모리로 공유 메모리를 통해 불필요한 메모리 중복을 막고 프로세스간 통신을 위해 사용된다.

buffer 는 data structure, meta info 등을 저장하는 공간으로 파일의 위치, 퍼미션, 날짜등의 inode 데이터가 된다.

cache 는 페이지, 파일, 패킷등의 실제 데이터 덩어리로 볼 수 있다. cache 의 목적은 최근 자주 사용되는 데이터를 메모리에 보관하여 재사용시 디스크까지 가서 않고 메모리에서 빠르게 액세스/로딩을 위해 사용된다.

리눅스에서는 현재 사용중이지 않는 데이터를 buffer 나 cache 로 저장하고 있다.

buffer 나 cache 는 os 가 사용하다가 어떤 프로세스가 실행되어 가용메모리(free)보다 많은 메모리를 필요로 할때 가용메모리로 바뀌게 된다.

따라서 실제 가용메모리 = free + buffers + cached 가 된다.


[예시]

아래는 free 명령을 실행한 결과이다.

전체 4037208KB 메모리중 3438984KB 가 사용되고, 가용메모리(free)는 598044KB 밖에 안되는 것처럼 보이지만

바로 아래줄에 -/+ buffers/cache 를 고려할 경우 사용중인 메모리는 1484256KB 이고 가용메모리는 2552772KB 이 된다.

즉 가용메모리 2552772KB = 598044KB(free) + 96392KB(buffers) + 1858336KB(cached) 가 된다.




[참고] 
free -t 로 total 파악할 수 있다.
또는

cat /proc/meminfo

또는

vmstat -w
을 사용하면

active: 실행 중인 프로세스가 사용중인 메모리

inactive: 실행 중이 아닌 프로세스가 점유하고 있는 메모리

를 확인 할 수 있다.

Visual C++ Detected memory leaks debugging

'Detected memory leaks!' 즉 메모리가 누수시 AfxSetAllocStop(number) 이용하면 쉽게 디버깅이 가능하다.
만약 출력창에 다음과 같이 메모리 누수가 나타나면
Dumping objects ->
{1359} normal block at 0x0139D7D8, 332 bytes long.
 Data: <                > 00 00 00 00 CD CD CD CD 00 00 00 00 00 00 00 00 
{1358} normal block at 0x0139D758, 64 bytes long.
 Data: <d:\Project\OCR-N> 64 3A 5C 50 72 6F 6A 65 63 74 5C 4F 43 52 2D 4E 

소스 코드 시작지점(main, init. 생성자....등)에서 {} 안에 있는 숫자를 파라미터로 설정하여 다음과 같이 사용한다.
AfxSetAllocStop(1359);

그리고 나서 F5 로 디버깅을 시작하면 메모리를 공간을 확보하는 시점(new, alloc()...)에 브레이크포인트가 걸린다.
이후 호출스택을 보면 어느시점에서 어떤 녀석이 메모리를 사용하려고 하는지 알수 있다.
결국 그 어떤 녀석이 나중에 메모리 해제가 안되는 것으로 파악되고 코드를 수정하면 된다.
AfxSetAllocStop 는 MFC 환경에서 사용되는 함수이다. 만약 MFC 환경이 아니라면 다음과 같이 _CrtSetBreakAlloc() 를 사용한다.
void main()
{
#if defined(WIN32) || defined(WIN64)
#ifdef _DEBUG
#include <crtdbg.h>
 // _CRTDBG_ALLOC_MEM_DF ==> _CLIENT_BLOCK 에 메모리를 할당에 대해서 덤프
 // _CRTDBG_LEAK_CHECK_DF ==> 프로그램이 종료될 때 자동으로 _CrtDumpMemoryLeaks() 를 호출하여 메모리 누수시 덤프
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 // 해제 안되는 new 의 파일과 라인수를 파악한다.
 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)

 // 메모리 누수시 블록숫자값(출력창의{1234})을 주면 메모리 공간을 확보하는 시점에 브레이크포인트가 걸린다.
 _CrtSetBreakAlloc(1359);
#endif
#endif
}