메모리란?
Process가 program을 실행되는데 필요한 가장 기본적인 자원중 하나이다.
- Process입장에서 address space(가상공간의 주소)내에서 Memory가 할당되고 해제되는 방식으로 사용된다.
- 그 후 커널이 각 process의 가상공간의 Memory영역을 물리적 Memory에 mapping한다.
- 그래서 process는 실제 물리적 Memory할당에 관여할 필요가 없다.
- 가상공간의 address space가 낮은주소 부터 높은 주소까지 만들어지고, 특징적으로 나누어진다.
- 커널에서 페이지 단위로 관리한다.
이 공간을 어떻게 할당하고 해제하는지 알아본다.
- Text 영역
- Initialized data 초기화된 데이터 영역
- Uninitialized data(bss) 초기화 되지 않는 데이터 영역
- heap 동적으로 할당되는
- static
Text Area
-process의 progam 코드, 컴파일되서 실행파일이 만들어지면 절대 고칠 수 없다 read only
Data
- 전역변수 영역으로 초기화된 data와 초기화 되지 않는 data(BSS, Block Started by Symbol)가 있다.
Heap
실제로 할당되는 공간은 다이나믹하게 할당하고 해제한다.
Stack
지역적으로 쌓여서 실행된다.
vars.c
- 전역변수(함수 밖에 있는, 함수안의 static)는 data
- malloc은 heap
- 지역변수, 매개변수는 stack, / stack의 공간들은 함수가 끝나면 자동적으로 해제된다.
- 그 이외이 여러 변수들 중 큰 변수들은 메모리공간을 할당한다. heap에
Dynamic Memory Allocation
프로그램 내에서 큰 메모리공간이 필요할 경우 heap 영역에 추가로 다이나믹하게(동적으로) 메모리공간에 할당해서 사용한다.
필요할 때마다 필요한 크기만큼 할당하고 해제한다.
유저레벨 프로세스가 한정된 자원 사용한다 그래서 필요할 때 필요한 크기만 할당한다. 사용하면 반환한다.
#malloc(), calloc(),reolloc(),free()
#include<stdlib.h>
void *malloc(size_t size);
해당 size만큼 heap영역에 할당을 한다. (기본단위 byte., void 포인터 ) |
size 할당 크기 |
return 메모리주소/ |
#include<stdlib.h>
void free(void *ptr);
heap영역에 해당 영역의 시작주소부터 메모리영역 해제 |
메모리 할당 예제
malloc(byte크기)
malloc(10*sizeof(int))
char로 캐스팅하면 char형의 크기 1byte크기로 메모리 할당 -> 40개
두번째는 int형 4byte크기로 -> 10개
동일한 크기라도 읽는 방법이 많다.
공간을 구조체 크기로 연속적으로 할당
예제 stud1.c
#include<stdlib.h>
void *calloc(size_t n, size_t size);
할당할 개수, space단위 --> n*size 할당되면 0으로 초기화 |
n : 크기 단위 size : 개수 |
return 첫번째 주소값 / null |
#inclue<stdlib.h>
void *realloc(void *ptr, size_t newsize);
재 할당 현재 할당 공간에 대한 포인터 주소, 크기 재조정해서 할당 |
*ptr : 포인터 주소 newsize ; 재할당할 크기 |
c경우에 해제해주지 않으면 운영체제가 재부팅되지 않는한 할당한 공간은 해제되지 않는다.
계속 할당만 하면 해당 시스템이 사용할 공간이 없어서 문제 심각해짐
꼭 free()로 해제 해줘야한다.
Memory Mapped File
file의 특정영역을 메모리 영역에 mapping시켜서 사용한다.
특정 file의 특정영역을 일고 쓸 때, 사용한다.
목적
- 매핑된 영역의 연산을 메모리에 데이터를 쓰는데 file에 써/읽진다.(auto-saving)
- 메모리와 file에 동시 써짐(위와 같은 말)
효율적인 이유는 일반적으로 파일을 오픈하고 쓰면 유저가 읽을 데이터 영역에 자체적으로 할당해야한다. ex dynamic static buffer, buffer에 쌓고 buffer가 메모리로 이중카피가 일어난다. 이거 방지
- buffer copy의 횟수가 줄어들어서 I/O성능을 올려준다.
- 인터프로세스 커뮤니케이션이 가능한다.
#include <sys/types.h>
#include <sys/mman.h>
caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset);
add: 할당될 메모리영역의 시작 주소 len: 얼마나의 공간을 할당할거냐 메모리 영역 크기 prot: 할당할 메모리 공간에 접근권한 설정 settting값 flags: mapping방식에 어떻게 할거냐 fd: mapping될 file descriptor offset: 어느 영역부터 mapping할거냐 |
return 매핑된 Memory area의 주소값 / MAP_FAILED라하는 에러값 반환 |
prot
여러 개를 OR한다.
OPEN된 FILE에 매치를 이루어져한다. (오픈할 때 권한보다는 낮아야한다.)
- PROT_READ : READ 가능
- PROT_WRITE : WRITE가능
- PROT_EXEC: 실행가능
- PROT_NONE : 아무것도 안됌
flags
- MAP_SHARED* : 특정영역에 wirtie 발생하면 file, memory sync해서 동일하게 적용
- MAP_PRIVATE*: 해당 파일에 직접하지 않고 카피본을 만들어서 wirte // 두개는 상호배재
- MAP_FIXED : 아까 arg 주소값을 result의 주소값이 똑같게 설정 // 안되어있으면 그저 reference 이다.
- MAP_NORESERVE : swap space를 만들지마라
#include < sys/types.h>
#include <sys/mman.h>
int munmap(caddr_t addr, size_t len);
해제하는 함수 |
addr : 해제 매모리 시작주소 len : 길이 |
return 0/ -1 |
mmcp.c 예제
#include<sys/mman.h>
#include<unistd.h>
int msync(const void *addr, size_t len, int flags);
메모리 map 영역에 의 데이터를 disk로 동기화 시키는 system call mmap 하면 읽고쓰고 받는 데이터를 메모리 인터페이스를 쓰지만 page cache에 써서 바로 동기가 안될 수도 있다. 그걸 바로 할 수 있게 하는 system call이다. |
addr : mmap되어 있는 특정 주소영역에 len : 길이까지 flags : option에 따라서 |
return 0/-1 |
flags
- MS_ASYNC : 싱크를 하는데 그때까지 기다리지 않는다. 동기화 시켜놓고 빠져나오고 다음 바로 실행
- MS_SYNC: 디스크에 다 써질때까지 기다리는다.
- MS_INVALIDATE : 그 파일에 매핑되어있는 다른 데이터를 INVALIND시켜라
MSYNC-EX.C
'시스템 프로그래밍' 카테고리의 다른 글
시스템 프로그래밍 10장 - Signal 1 (0) | 2020.06.10 |
---|---|
시스템 프로그램 9장 - Semaphore (0) | 2020.06.10 |
시스템 프로그래밍 7장 - Record Lock (0) | 2020.05.06 |
시스템 프로그래밍 7장 - Thread : Condition variable (0) | 2020.05.06 |
시스템 프로그래밍 6장 - Thread : Synchronization (0) | 2020.05.06 |