CS/Operating System

15. Dynamic allocation in Linux

공부중인학생 2023. 12. 24. 15:29

코드를 작성할 때 malloc 사용하면 heap segment의 일정 부분이 할당됩니다. 프로세스의 세그먼트 일부분을 할당할 때 리눅스가 heap을 어떻게 핸들링하는지 알아보겠습니다.

 

 

 

OS에서는 프로세스의 memory context를 구성하는 기본 단위를 세그먼트라고 부르는데 리눅스에서는 virtual memory area(VMA)라고 부릅니다. virtual memory area은 각 프로세스들이 갖는 logical address space에 존재하는 일정한 메모리 영역입니다. 

 

이런 세그먼트를 사용자가 직접 만들 수 있는데 이때 system call mmap이 사용이 됩니다. 

 

 

 

위 사진은 리눅스가 관리하는 유저 프로세스의 메모리 레이아웃을 도식화한 것입니다. 파란색 박스는 세그먼트, VMA로 보면 됩니다. 이때 힙 세그먼트, 스택 세그먼트  중간에 있는 anonymous memory objects는 사용자가 mmap을 통해서 임의로 만드는 세그먼트입니다.

 

리눅스에서는 C코드를 작성할 때 malloc을 통해 dynamic memory object를 할당받으면 무조건 힙 세그먼트에서 메모리를 할당하는 것이 아닙니다. 사용자가 요구하는 메모리 크기가 리눅스가 가지고 있는 threshold 값보다 작으면 힙 세그먼트에서 할당을 진행하지만 사용자가 굉장히 큰 memory object를 요구하면 힙에서 가져는 주는 것이 아니라 virtual address space에서 새로운 세그먼트를 만들어서 요구한 memory object 하나만 통째로 담아서 할당해 줍니다. 이렇게 큰 request를 처리하게 위해서 별도로 만들어진 세그먼트를 anonymous memory object라고 부릅니다. 

 

 

 

이렇게 request에 따라 다른 곳에서 할당하는 이유는 paging을 진행할 때 memory management system에서 발생되는 overhead 때문입니다. 유저 프로세스가 자신의 logical space에서 특정 영역을 액세스 하려면 해당 logical address에 대한 정보를 가지고 있는 page table을 만들어야 합니다.

 

heap의 경우에는 table entry가 다 만들어져 있지만 annoymous memory object는 page table entry를 만들지 않습니다. 그래서 굉장히 큰 memory object를 만들 때 annoymous memory object로 만들면 page talbe entry를 만들지 않아서 over head를 줄일 수 있습니다.

 

작은 오브젝트들은 이미 테이블에 매핑되어 있는 힙에서 할당하고 크기가 커서 힙에서 할당이 안 되는 것들은 언맵된 상태로 logical address space의 빈 영역을 할당해 주는 것입니다. anonymous memory object(AMO)가 logical address space에 액세스를 했는데 page table entry가 없다면 page fault exception이 발생하게 됩니다. 

 

 

 

AMO로 할당되는 기준은 일반적인 데스크톱의 OS의 threshold가 4MB이므로, 4MB보다 큰 메모리 오브젝트를 동적으로 할당하려고 하면 mmap을 통해서 AMO를 할당하게 됩니다. 모바일 환경과 같은 메인 메모리가 더 작고 storage도  flash로 구성되는 시스템에서는 threshold가 훨씬 더 작습니다. 

 

 

 

이번에는 힙에서 다루는 garbage collection을 알아보겠습니다. 힙을 통해서 dynamic memory allocation을 하게 되면 힙에서 memory chunk 하나를 할당받게 됩니다. 사용을 다한 다음에는 반환을 해야지만 사이즈가 유한한 힙은 재사용할 수 있습니다. 이때 반환을 하지 않은 상태에서 프로그램이 오래 실행된다면 사용가능한 힙의 메모리 양이 점점 줄게 됩니다. 

 

이렇게 힙이 고갈되면 더 이상 프로세스를 수행할 수 없기 때문에 중지됩니다. memory allocation은 세마포어의 P, V처럼 unstructured operation 이기 때문에 malloc 이후 free를 하지 않더라도 알기 힘듭니다. 그리고 memory leak와 같이 프로그램 버그로 인해서 메모리 반환이 일어나지 않는 경우도 있습니다.

 

memory reclamation에 대해 알아볼 것인데 memory reclamation이란 할당받았는 데 사용하지 않는 메모리를 반환하는 것입니다. 수동으로 반환하거나 자동으로 반환하는 방법이 있는데 자동으로 반환하는 기능을 garbage collection이라고 합니다. 

 

 

 

garbage란 dynamic memory object로 프로그램에 존재하고 있지만 액세스 되지 못하는 memory object를 의미합니다. 엑세스 하지 못하는 이유는 memory object에 대한 포인터를 상실되었지 때문입니다. 그래서 garbage collection은 메모리 경로가 상실된 dynamic memory object를 자동적으로 heap으로 반환해 주는 mechanism입니다.

 

 

 

garbage collection은 주기적으로 heap의 사용 가능한 메모리 량이 기준치보다 낮아지면 모든 프로그램의 수행을 중단시키고 수행됩니다. 이를 통해 memory leak을 해결할 수 있습니다. C 같은 경우는 자동으로 garbage collection을 지원하지 않기 때문에 malloc 이후 free를 놓치게 되면 memory leak가 바로 발생합니다. 

 

garbage collection은 포인터를 이용해서 프로그램에 존재하는 모든 영역을 다 탐색하고 표시합니다. 이후 표시가 되어있지 않은 오브젝트가 존재할 때 이 memory object를 garbage라고 부릅니다. 이걸 반환하려면 어떤 변수들이 데이터인지 포인트인지 알아야 합니다. (메모리 오브젝트에 대한 타입 정보를 알아야 함)

 

이런 타입 정보를 제공해 줘야 자동으로 collection이 진행됩니다. 자바나 파이썬의 경우 항상 심벌 테이블을 가지고 수행하니까 자동으로 지원이 됩니다. garbage collection을 정리하자면 malloc 후 free 하지 않아 쌓이는 메모리 오브젝트들이 garbage화 되고 이게 계속 쌓이면 memory leak가 발생하는데 이런 문제를 해결해 주는 방법입니다.

dangling pointer는 그 오브젝트에 대한 포인터를 상실하는 문제인데 여러 요인으로 발생합니다. free를 2번 진행해 더블 프리 버그가 생길 수 있는데 이것 또한 garbage collection으로 해결이 가능합니다. 

 

 

 

garbage collection은 지금 액세스 되고 있는 메모리 로케이션에 대한 정보를 프로그래밍 시스템으로부터 얻을 수 있어야 합니다. 이런 작업을 mark라고 부릅니다. mark를 다 하고 난 다음에는 mark가 되지 않은 메모리 오브젝트를 힙으로 반환하는 작업을 합니다. 이런 단계를 sweep이라고 합니다. 

 

 

 

Reference counter approach는 어떤 메모리 오브젝트가 있으면 그 메모리 오브젝트마다 레퍼런스 카운터를 표시해 둡니다. 포인팅을 당하면 레퍼런스 카운트값을 증가시킵니다. 그리고 free를 하면 레퍼런스 카운트 값은 decrement가 됩니다. 이렇게 진행하다 보면 레퍼런스 카운트 값이 0이 되는 오브젝트가 있게 되는데 이때 garbage collection이 실행되어 0인 값을 찾아 반환하게 됩니다. (안 쓰는 것을 반환하는 것)

 

 

 

이런 garbage collection은 굉장히 비싼 오퍼레이션으로 20%의 CPU time을 소모할 때도 있습니다. 이렇게 성능저하가 심하게 생기므로 사용자의 response에 영향이 가지 않도록 잘 분산하여 진행해야 합니다.

'CS > Operating System' 카테고리의 다른 글

17. Paged segmentation  (0) 2024.01.23
16. Segmentation  (1) 2024.01.10
14. GNU Linker  (1) 2023.12.18
13. 힙(Heap)  (1) 2023.12.18
12. Deadlock solution  (0) 2023.12.12