좋은 내용이군요.
이론으로는 알고 있는 내용이지만 이렇게 실재로 눈으로 보는것은 참 의미있다고 생각합니다.
헌데 여기서 나오는 rss 는 smaps 에 나오는 rss, pss 와 같은 의미일까요?
결과를 다 써놓고 정리하자니 벌쭘하지만.
VSZ와 RSS는 뭘까? man 페이지의 ps 항목에서 설명하는 두 파라미터의 설명은 다음과 같다.
VSZ
virtual memory size of the process in KiB (1024-byte units). Device mappings are currently excluded; this is subject to change. (alias vsize).
RSS
resident set size, the non-swapped physical memory that a task has used (in kiloBytes). (alias rssize, rsz).
아 뭐야. 몰라. 어려워.
간단히 말하자면 VSZ는 가상 메모리의 크기이고, 현재 디바이스 매핑에서는 제외되어 있다는 의미인 것 같다. RSS는 실제 메모리가 세팅된 크기이고, 스와핑이 되지 않은 물리적 메모리가 해당 task에 쓰이고 있는 양을 의미하는 것 같다.
그러니까 VSZ 크기만큼을 reserve 해놓고 실제로 물리적 메모리가 사용하고 있는 것은 RSS 크기만큼이라는 것인데.
Shared Memory에서 테스트, 닫기
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> /* for strerror */
#include <errno.h> /* for errno */
#include <sys/ipc.h> /* for shmat, shmget, shmdt, shmctl */
#include <sys/shm.h> /* for shmat, shmget, shmdt, shmctl */
#define SHMSIZE (1024 * 1024 * 1024) /* 1G byte */
#define SHMKEY 0x10102020
int main(void)
{
char *buf;
int ret, i;ret = shmget(0x10102020, SHMSIZE, 0666|IPC_CREAT|IPC_EXCL);
if (ret < 0) {
fprintf(stderr, "shmget(%lx): %s\n", SHMKEY, strerror(errno));
exit(-1);
}
buf = shmat(ret, NULL, 0);
if (buf == (char *)-1) {
fprintf(stderr, "shmat(%lx): %s\n", SHMKEY, strerror(errno));
exit(-1);
}/* memory I/O를 일으키는 for loop. 나중에 뺄거다. */
for (i = 0; i < SHMSIZE; i++) {
*(buf + i) = (i % 256);
}system("ps u");
shmdt(buf);
shmctl(ret, IPC_RMID, NULL);return 0;
}
1메가의 공유메모리를 설정하고 각 byte마다 I/O를 일으킨 후에 ps 결과를 보고 자동으로 공유메모리를 정리한 후에 종료한다.
이 실행 결과는 다음과 같다.
공유메모리를 할당하는 부분만 놓고 I/O를 일으키는 부분을 제외해보면,
Shared Memory를 attach 해놓는다고 해서 다 물리 메모리에 올라가는 구조는 아닌듯 하다. 어딘가 reserve 해놓았다가 필요한 경우 RSS에 올려서 사용할 수 있도록 한다. 실제 물리 메모리에 매핑된 크기는 RSS에 기록된 크기와 같다.
Shared Memory에서 테스트, 닫기
그런데, 이것이 Shared Memory가 아니라 Local Memory라면?
Local Memory에서 테스트, 닫기
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> /* for strerror */
#include <errno.h> /* for errno */
#define MEMSIZE (1024 * 1024 * 1024) /* 1G byte */
int main(void)
{
char *buf;
int ret, i;buf = malloc(MEMSIZE);
/* memory I/O를 일으키는 for loop. 나중에 뺄거다. */
for (i = 0; i < MEMSIZE; i++) {
*(buf + i) = (i % 256);
}
system("ps u");
free(buf);return 0;
}
소스의 크기는 좀 더 작네. (당연하지. 공유메모리 관리 부분이 다 빠졌으니까.)
이 결과는?
Local Memory에서 테스트, 닫기
malloc 혹은 Shared Memory를 attach 해서 확보해 놓은 메모리라고 해도, 실제 I/O를 일으키지 않으면 VSZ 영역에 예약만 되어 있을 뿐이다. 하지만 실제 I/O를 일으키게 되면 RSS 영역에 확보되게 되고, 이것은 실제로 물리적 메모리에 할당된다. (이 동작은 Local Memory와 Shared Memory가 완벽하게 동일하다.)
결론적으로 ps u 옵션에서 볼 수 있는 RSS는 실제 프로세스가 물리 메모리에서 점유하고 있는 메모리이며, VSZ까지 증가할 수 있다. 하지만 Shared Memory 등의 방식으로 각 프로세스는 메모리를 공유할 수 있기 때문에 RSS의 총 크기 합은 서버의 물리 메모리보다 클 수 있다. 프로세스가 동작하는 도중 별도의 메모리 할당 없이 RSS는 VSZ까지 증가할 수 있다. 이것은 정상적인 상황이다.
이 소스는 Linux Kernel 2.6.18 x86_64, Red Hat Enterprise Linux AS release 3에서 테스트 되었다.
이상.
'Programming > Linux_Kernel' 카테고리의 다른 글
Platform_get_irq & struct resource (4) | 2010.04.06 |
---|---|
간단히 system lock up 상황 만들기 (0) | 2010.03.25 |
linux proc 정보 (0) | 2010.02.25 |
linux 병목현상 분석 : latencytop (0) | 2010.02.23 |
각 HW block clock control 하기 - linux 2.6.29 (0) | 2010.02.17 |