-
[Java] 자바의 메모리 구조 정리IT/개발(자바, 서블릿, 스프링 등) 2019. 12. 7. 18:35
자바 프로그램은 JVM에 의해 실행된다. JVM은 자바 프로그램을 실행하면서 필요한 데이터를 메모리에 생성한 후에 사용한다. 이 때 메모리를 세가지 영역으로 구분하여 사용한다. Code 영역 / Heap 영역 / Stack 영역.
- 코드 영역(메서드 영역)
클래스 파일을 실행하면 JVM의 클래스 로더가 클래스 파일을 실행하기 위해 필요한 클래스 파일을 메모리에 올린다. 자바 소스 파일에 정의한 클래스에 관한 정보와 코드를 코드 영역에 만들어준다.
- 힙 영역
클래스를 설계하고 이를 사용하려면 메모리에 해당 클래스의 인스턴스를 생성해야 한다. new 명령문으로 인스턴스를 생성하면 메모리의 힙 영역에 생성된다. 그런데 클래스의 메서드는 실행 시작 시점에 클래스 로더에 의해 코드 영역에 만들어진다. 따라서 실제로 힙 메모리에 필드만 생성된다. 인스턴스가 가지고 있는 메서드는 코드 영역에 생성된다.
- 스택 영역
필드는 클래스의 속성을 나타내는 변수이다. 지역변수는 메서드가 실행되면서 필요한 데이터를 잠시 유지하기 위해 사용하는 변수로 메서드 내에서 선언한 변수이다. 필드는 new 명령문에 의해 객체가 생성될 때 힙에 생성되지만, 지역변수는 메서드가 호출되어 실행될 때 스택에 생성이 된다. 지역변수가 스택에 생성되는 시점은 메서드가 호출되어 실행될 때이다. 메서드 실행 시 스택에 생성된 지역변수는 메서드의 실행이 종료될 때 스택에서 자동으로 삭제 된다. 소멸된다.
자바 프로그램은 힙 메모리에 직접 접근할 수 없다. 직접 접근할 수 있는 메모리는 오직 스택뿐이다. 따라서 자바에서는 스택 메모리에 참조변수를 선언하고 이 변수에 힙 메모리에 생성된 인스턴스의 참조 정보를 저장해서 접근하는 방식을 사용한다. 즉, new 명령문이 인스턴스를 힙 메모리에 할당할 때 반환하는 참조 정보를 변수에 저장해 사용함으로써 해당 인스턴스에 접근할 수 있다. 참조변수에는 할당된 메모리의 위치 정보가 저장된다.
class Calc { public int sum(int num1, int num2){ return num1+num2; } } public class CalcTest(){ public static void main(String[] args){ Calc calc = new Calc(); calc = null; calc.sum(1, 1); } }
위의 소스코드를 실행하면 NullPointerException이 발생한다. 지역변수 calc에 null 값을 저장했기 때문이다. 자바에서 널은 '아무 값도 가지지 않는다'는 뜻이다. 이 때 힙에 생성된 Calc 인스턴스의 참조 정보를 스택에서 아무도 가지고 있지 않으므로 접근할 방법이 없다. 이런 상황을 참조가 끊겼다고 한다. 참조가 끊긴 인스턴스는 더이상 사용할 수 없고, 메모리만 낭비한다. 이렇게 가비지가 된 인스턴스들은 JVM의 가비지 콜렉션에 의해 메모리에 삭제된다.
* 필드 초기화
필드는 메모리에 생성된 후 자동으로 초기화되지만, 지역변수는 자동으로 초기화되지 않으므로 선언과 동시에 초기화 작업을 해야 한다. new 명령문으로 클래스의 인스턴스를 생성하면 해당 클래스에 선언한 필드가 힙 영역에 생성된다. 이때, 각 필드는 별도로 초기화하지 않아도 자동으로 초기화된다. 이때의 초깃값은 필드의 데이터 타입에 따라 다르다.
필드 타입별 초깃값
필드 타입 값 byte 0 short 0 int 0 long 0L float 0.0F double 0.0D char '\u0000' boolean false 모든 참조변수 null 'IT > 개발(자바, 서블릿, 스프링 등)' 카테고리의 다른 글
[Java] this 키워드로 생성자 호출 (0) 2019.12.09 [Java] 정적 멤버 개념 (static 키워드 개념) (0) 2019.12.09 [Java] 클래스 객체 인스턴스 용어 정리 (0) 2019.12.07 [Java] 가변 길이 인자 개념과 사용법 (0) 2019.12.07 [Java] 메서드 오버로딩 (0) 2019.12.07