-
자바의 메모리관리, 가비지 컬렉션개발 2020. 12. 13. 23:12
자바의 메모리 공간은 크게 Static , Stack, Heap 영역으로 구성된다.
Static
- 필드 부분에서 선언된 변수(전역변수)와 정적 멤버변수(static이 붙은 자료형)은 Static 영역에 저장한다.
- Static 영역에 저장된 데이터는 프로그램의 시작부터 종료가 될 때 까지 메모리에 남아있게 된다. 즉 프로그램 종료 전까지 어느 영역에서든 Static영역에 저장된 값을 사용할 수 있다는 뜻이다. 하지만 남용할 경우 메모리 공간이 부족해진다.
Stack
- Stack 메모리 영역에는 우리가 평상시에 작성하던 메소드 내에서 정의하는 기본 자료형(원시 타입)에 해당되는 지역변수의 데이터의 값이 저장되는 공간이 Stack영역이다. 해당 메소드가 호출될 때 메모리에 할당되고 종료되면 메모리가 해제된다.
- Heap 영역에 생성된 Object 타입의 데이터들에 대한 참조를 위한 값들이 할당된다.
- Stack 영역에 있는 지역 변수의 경우 visibility를 가지게 된다.
- 각 Thread는 고유의 stack을 가진다.
- 자료구조 Stack과 마찬가지로 LIFO의 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 사라진다.
Heap
- Heap 메모리 영역에는 참조형 데이터 타입을 갖는 객체(인스턴스), Object Type(array, List...) 등은 Heap 영역에 데이터가 저장된다.
- Stack 영역의 공간에서 실제 데이터가 저장된 Heap영역의 참조값을 new 연산자를 통해 리턴 받는다. 실제 데이터를 갖고 있는 Heap 영역의 참조 값을 Stack 영역의 객체가 갖고 있다.
- Heap영역에는 주로 긴 생명주기를 가지는 데이터들이 저장된다.
- 애플리케이션의 모든 메모리 중 stack에 있는 데이터를 제외한 부분이라 봐도 무방하다.
- 몇개의 스레드가 존재하든 상관없이 단 하나의 heap 영역만 존재한다.
- Heap 영역에 있는 오브젝트들을 가리키는 변수들이 stack에 올라가게 된다.
- Heap영역에 저장된 데이터가 더이상 불 필요 하다면 메모리 관리를 위해 JVM에 의해 알아서 해제되는데 이 기능을 가비지 컬렉션(GC)라 한다.
가비지 컬렉션(GC)
C, C++에서는 OS level의 메모리에 직접 접근 하기 때문에 free()라는 메소드 호출을 통해 할당 받은 메모리를 명시적으로 해제해준다. 그렇지 않으면 메모리 누수가 발생한다. 이는 다른 프로그램에도 영향을 줄 수 있다.
반면 자바의 경우 OS의 메모리 영역에 직접 접근하지 않고 JVM 가상머신을 이용하여 간접적으로 접근한다.
JVM은 C로 쓰여진 또 다른 프로그램으로 Object가 필요해지지 않는 시점에서 알아서 free()를 수행하여 메모리를 확보한다. 웹 애플리케이션 개발시 모든 것을 직접 다 개발하지 않고 검증된 라이브러리나 프레임워크를 이용하는 것과 같은 맥락이다.
자바는 JVM을 사용함으로써 OS 레벨에서의 memory leak은 불가능 하게 된다는 장점이 존재한다.
자바가 메모리 누수현상을 방지하는 다른 방법은 가비지 컬렉션이 존재한다.
가비지 컬렉션의 주 대상은 Heap영역의 Object 중 Stack에서 도달 불가능한 영역의 오브젝트 들이다.
String s = "a"; 를 실행하면 Stack 에는 s 가 Heap에는 String a가 쌓이게 되고 s는 a에 할당 된다.
그 다음 s+= "aaa";를 실행하면 s는 Heap에 새로 쌓인 aaaa에 할당 하게되고 a와의 연결이 해제 된다.
즉, Stack에는 새로운 변수가 할당되지 않고 Heap에 새로운 값이 생성되어 레퍼런스하게 되는 것이다.
JVM의 가비지 컬렉터는 도달 불가능한 오브젝트를 우선적으로 메모리에서 제거하여 메모리 공간을 확보하기 때문에 위 상황에서 가비지 컬렉션이 동작하게 된다면 heap에서 a값은 메모리에서 제거 된다.
이러한 가비지 컬렉션 과정은 Mark and Sweep이라고 한다.
JVM의 가비지 컬렉터가 스택의 모든 변수를 스캔하면서 각각 어떤 오브젝트를 레퍼런스 하고 있는지 찾는 과정이 Mark이고, 도달 가능한 오브젝트가 레퍼런스하고 있는 오브젝트 또한 marking작업을 한다. marking 작업시 모든 스레드는 중단되므로 아무생각 없이 gc를 호출하면 안된다.
이 후 mark 되어 있지 않은 모든 오브젝트들을 힙에서 제거하는 작업을 Sweep이라한다.
가비지 컬렉션이라 하면 쓰레기를 수집하는 것 같지만 실제로는 사용하는 것을 mark하고 그 이외의 것들을 모두 지우는 작업이다.
'개발' 카테고리의 다른 글
URI와 웹 브라우저 요청 흐름 (0) 2021.01.05 쿠키&세션 (0) 2020.12.23 스프링과 스프링 부트의 차이 (0) 2020.12.08 MSA? (0) 2020.12.04 Rest API ? (0) 2020.12.03