Hi there!

I am a student studying computer science.

시스템 프로그래밍

시스템 프로그래밍 8장 - Memory 1

만능성구 2020. 6. 10. 13:34
728x90

메모리란?

Processprogram을 실행되는데 필요한 가장 기본적인 자원중 하나이다.

- 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한다.

OPENFILE에 매치를 이루어져한다. (오픈할 때 권한보다는 낮아야한다.)

- 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

728x90