프로그램을 실행할 때 모든 영역이 다 필요한 건 아니다. PC(Program Counter)가 가리키는 부분과 관련된 데이터, 힙, 스택영역이 필요하기 때문에 OS는 가상메모리 라는 걸 활용한다.
가상메모리 = Main Memory + Hard Disk
즉 필요없는 부분은 하드디스크에 뒀다가 필요할 때 부른다.
이 과정을 Page Swapping 이라고 부른다.
프로세스의 모든 영역이 Swap의 대상이므로 Heap과 Stack 영역도 그로부터 자유롭지 못하다.
여기서 드는 의문
그러면 OOM(Out of Memory)은 왜 발생하지?
이 에러는 할당된 범위를 넘어선 영역에 대해서 메모리 할당을 요구할 때 발생한다. 보통 Runtime 때 Heap 영역에서 발생한다.
Heap을 Swapping 하면 계속 할당할 수 있지않을까? 하는 의문이 들었는데, 여러가지 문제가 있다.
1. 하드웨어 한계
- 32bit CPU는 4GB까지의 주소만 사용할 수 있다. 이 범위를 넘어서면 OutOfMemory다.
- 64bit CPU이지만 RAM이 4GB이면 4GB까지만 할당할 수 있다. 이 범위를 넘어서면 OutOfMemory이다.
2. 소프트웨어적인 한계
- JVM 같은 Machine에서 한계를 정해놨을 수도 있다.
예를 들어서
이런 식으로 되어있으면 Xms1990m 설정은 이 JVM은 1990M을 최대 힙 사이즈로 쓰겠다는 뜻이다.
1990M = 2,086,666,240 Byte 이다.
테스트를 하면 이런 모양이 된다.
532254060 개의 Integer는 2,129,016,240 Byte이다.
최대 힙 크기를 넘어서기때문에 다소 의아하지만 내 추측으로는
1) ArrayList는 배열이 꽉 찰때마다 이전 크기의 두 배인 배열을 할당한다. 그리고 "Logical Space"는 실제로 변수가 할당될 때 물리 메모리와 Mapping된다. 그래서 미리 배열을 할당한 크기가 532,254,060이고, 이 배열에 원소를 하나씩 넣어가는 과정에서 OOM이 발생했다. 그 결과 ArrayList의 크기가 최대 Heap을 넘어가게 됐다.(Size는 ArrayList의 헤더에 이미 입력되어있으므로)
이다.
'컴퓨터 상식' 카테고리의 다른 글
[Java] Boxing vs No Boxing 속도 차이 (0) | 2020.11.16 |
---|---|
HTTP 버전 별 특징 (0) | 2020.11.15 |
크롬(Chrome)의 각 탭은 프로세스(Thread)다. (0) | 2020.11.05 |
REST API 정리 (0) | 2020.10.28 |
Ajax는 Restful 할 수 있는가. (0) | 2020.10.22 |