본문 바로가기
프로그래밍/Java

[Java | 자바] Java의 메모리 관리

by 불타는홍당무 2017. 4. 12.


1. 일반적인 메모리 관리
- Java 가비지 플랫폼은 자도으로 사용했던 메모리를 해제하는 가비지 컬렉션(Garbage Collection) 기능을 수행한다.
- 프로그래머가 직접 메모리 관리를 하는 경우에 생길 수 있는 문제점
=> 할당된 메모리 영역 초과 : Java 언어는 참조현 변수들에 대한 산술 연산을 금지시킴으로써 C언어의 포인터로 인해 발생되었던 메로리 초과 문제를 최소화
=> 메모리 부족 : 프로그래머가 크기가 작은 메로리의 생성, 해제를 자주 반복할 경우, 실제 남아 있는 메모리는 충분하지만 연속적인 메로리 공간의 확보가 어렵게 되어 시스템에서 '메모리 부족' 에러가 발생
=> 메모리 영역을 벗어남 : 객체를 생성하여 메모리 할당을 받았지만, 이를 해제하는 것에 대해서 고려하지 않은 채 프로그램이 영역을 벗어나면, 그 메모리는 할당한 채 더 이상 쓸 수 없는 메모리가 됨

*메모리 누수 : 할당받은 메모리가 프로그래머의 잘못으로 인해 계속 늘어나게 되는 현상. 메모리 누수가 심해지면 결국 사용할 메모리가 부족.


2. Java의 메모리 관리
- JVM 내부에서 가비지 컬렉션 기능을 담당하는 가비지 컬렉터(Garbage Collector)의 동작에 의해 가능
- 가비지 컬렉터 : 프로스서의 대기시간에 메모리 상황을 추적하여 더 이상 사용하지 않는 메모리를 자동으로 해제
- Java에서는 프로그래머가 메모리 누수나 메모리 부족, 메모리 Scope을 벗어난 문제 등을 신경쓰지 않아도 됨.
- 가비지컬렉터는 객체를 생성할 때 할당되는 메모리를 참조하는 참조형 변수가 하나도 없는 메모리를 찾아 해제
- 할당된 메모리를 참조하는 변수들을 카운트하는 카운터를 두어 이 값이 0이 되는 메모리가 가비지컬렉션의 대상

*간접참조 : 힙에 객체의 내용이 있다면 중간에 그 곳을 가리키는 메모리 영역(핸들 메모리)이 있고, 스택에 잇는 변수가 핸들 메모리를 참조해서 실제 힙의 주소를 얻은 후 힙의 실제 내용을 참조하게 되는 방식
=> 직접 참조의 경우 스택에 있는 변수가 힙 메모리의 실제 주소를 가지고 있어 직접 참조하게 되는 방식
=> 자주 참조되는 변수나 객체가 있다면 직접 참조 방식이 훨씬 뛰어난 성능을 보임
=> 가비지 컬렉션의 경우(메모리를 지우거나 참조값을 바꾸는 경우) 직접 참조 방식에서는 값이 없어지거나 사라져야 하는 변수에 대해 일일이 포인터를 지워줘야 함
=> 간접 참조 방식의 경우 핸들 메모리만 수정해주면 되므로 간단해짐
=> Virtual Machine에서는 스택과 힙 메모리를 사용하며 스택에는 프로그램에서 사용하는 변수, 함수 이름 등이 수행 순서에 맞게 적재되어 있고, 힙 메모리에는 실제 스택에 있는 변수나 함수의 내용이 적재됨
=> 스택에는 실제 값이 존재하는 곳의 포인터를 가지므로 사용량의 크기가 크지 않으나 힙의 경우 사용량이 거지게 됨. 만약 힙 메모리를 다 사용하면 다면 추가 java.lang.OutOfMemory 오류가 발생함.