JVM의 구조와 메모리 모델 JVM의 내부 구조 클래스 파일 클래스 로더 메소드(method) 영역 힙(heap) 영역 라이브러리 클래스 로더 메소드(method) 영역 -메소드의 바이트코드 -클래스 변수 힙(heap) 영역 -객체 스택(stack) 영역 -매개변수 -지역변수 PC 레지스터 Native 메소드 스택 실행시간 데이터 영역(Runtime data area) Native 메소드 라이브러리 Native 메소드 인터페이스 실행 엔진
JVM의 구조와 메모리 모델 메소드 영역(Method area) 힙 영역(Heap area) 스택 영역(Stack area) 메소드와 클래스 변수를 저장하기 위한 공간 모든 프로그램에 의해 공유 힙 영역(Heap area) 동적으로 할당하여 사용할 수 있는 메모리 주로 실행시간에 생성되는 객체를 저장 스택 영역(Stack area) 메소드 호출 시 메소드의 매개변수, 지역변수, 임시변수등을 저장하기 위한 스택 구조의 메모리 실행중인 프로그램에 따라 스택 프레임 할당 PC 레지스터 JVM이 현재 수행할 명령어의 주소를 저장 Native 메소드 스택 Native 메소드를 호출할 때 native 메소드의 매개변수, 지역변수 등을 저장
프로그램 실행과 메모리 class MemoryTest { static int total = 0; public static void main(String[] args) { int x=10, y=20, z; //1번 z=add(x,y); } static int add(int a, int b) { total++; //2번 return(a+b);
프로그램 실행과 메모리 (1) 클래스 파일의 로딩 시점 두 개의 메소드와 클래스 변수가 메소드 영역에 저장 메소드 영역 스택 영역 힙 영역 total main() 메소드의 바이트 코드 add() 메소드의 바이트 코드
프로그램 실행과 메모리 (2) main() 메소드의 호출 시점 “1번”위치 main() 메소드가 호출되고 지역변수 x,y,z가 초기화 된 상태 args(문자열의 배열)에는 값이 주어지지 않았으므로 null 메소드 영역 스택 영역 힙 영역 total main() 메소드의 바이트 코드 z ? add() 메소드의 바이트 코드 y 20 main frame x 10 args null
프로그램 실행과 메모리 (3) add() 메소드의 수행시점 “2번”위치 add() 메소드를 위한 스택 프레임 할당 add() 메소드의 지역 변수 할당 total 값 증가 메소드 영역 스택 영역 힙 영역 total 1 main() 메소드의 바이트 코드 b 20 add frame a 10 z ? add() 메소드의 바이트 코드 y 20 main frame x 10 args null
프로그램 실행과 메모리 (4) add() 메소드의 반환 시점 add() 메소드의 수행 결과가 z에 저장되고 add() 메소드를 위한 프레임 제거 메소드 영역 스택 영역 힙 영역 total 1 main() 메소드의 바이트 코드 z 30 add() 메소드의 바이트 코드 y 20 main frame x 10 args null
인스턴스 생성의 예 class Exam { class MemoryTest2 { int c,d; public int add(int a, int b) { c = a + b; return c; } public int multi(int a, int b) { d = a * b; return d; class MemoryTest2 { public static void main(String args[]) { int sum,multi; int x,y; x = Integer.parseInt(args[0]); y = Integer.parseInt(args[1]); //1번 Exam ob1 = new Exam(); Exam ob2 = new Exam(); //2번 sum = ob1.add(x,y); multi = ob2.multi(x,y); System.out.println("입력한 값의 합은" + sum + "입니다"); System.out.println("입력한 값의 곱은" + multi + "입니다"); }
인스턴스 생성의 예 (1) main() 메소드가 수행되는 시점 “1번” 위치 프로그램 실행 시 두 개의 매개변수 지정(10,20) 두 개의 매개변수를 힙 영역에 문자열 객체로 저장 x,y 에는 정수로 변환된 값이 저장 메소드 영역 스택 영역 힙 영역 MemoryTest2 클래스 main() 메소드 바이트 코드 y 20 Exam 클래스 add() 메소드 바이트 코드 multi() 메소드 x 10 main frame multi ? sum ? args[1] args[0] 20 args 10
인스턴스 생성의 예 (2) 객체가 생성되는 시점 “2번” 위치 ob1, ob2 객체가 힙 영역에 생성 각각의 객체에는 두 개의 객체 속성 변수가 저장 메소드 영역 스택 영역 힙 영역 MemoryTest2 클래스 ob2 main() 메소드 바이트 코드 ob2 d 0 c 0 ob1 y 20 Exam 클래스 add() 메소드 바이트 코드 multi() 메소드 ob1 x 10 d 0 main frame multi ? c 0 sum ? args[1] args[0] 20 args 10
인스턴스 생성의 예 (3) 객체의 메소드 수행 시점 두 개의 객체가 생성된 다음 add() 메소드와 multi() 메소드가 수행된다 아래 그림은 add() 메소드 수행 후 multi() 메소드가 수행되는 시점 메소드 영역 스택 영역 힙 영역 b 20 multi frame MemoryTest2 클래스 main() 메소드 바이트 코드 a 10 ob2 ob2 d 200 c 0 ob1 Exam 클래스 add() 메소드 바이트 코드 multi() 메소드 y 20 ob1 x 10 d 0 main frame multi 200 c 30 sum 30 args[1] args[0] 20 args 10
배열과 메모리 class MemoryTest3 { public static void main(String[] args) { int a[] = new int[] {1,2,3}; a = new int[] {5,6,7,8}; System.out.println(a[3]); //1번 int b[][] = new int[][] {{1,2,3},{4,5},{6,7,8,9}}; System.out.println(b[2][3]); //2번 String s1 = "Hi Java"; System.out.println(s1); String s2[] = new String[] {"Hi","Java"}; System.out.println(s2[1]); //3번 }
배열과 메모리 (1) 배열의 생성과 변환 “1번” 위치 3개의 요소를 가진 배열 a를 생성한 후 다시 배열 a에 4개의 요소를 가진 배열을 할당 처음 생성된 3개의 요소를 가진 배열은 쓰레기 수집된다 메소드 영역 스택 영역 힙 영역 main() 메소드 바이트 코드 5 6 7 8 a main frame args null 1 2 3 JVM 쓰레기 수집
배열과 메모리 (2) 2차원 배열과 문자열의 생성 다차원 배열은 1차원 배열의 배열로 나타낸다 “2번” 위치 메소드 영역 스택 영역 힙 영역 main() 메소드 바이트 코드 6 7 8 9 b[2] b[1] b[0] 4 5 b 1 2 3 a main frame 5 6 7 8 args null
배열과 메모리 (3) 문자열과 문자열 배열의 생성 “3번” 위치 문자열을 객체로 취급하여 힙 영역에 저장 문자열의 배열은 문자열 객체의 배열로 취급 메소드 영역 스택 영역 힙 영역 “Java” s2[1] s2[0] “Hi” main() 메소드 바이트 코드 “Hi Java” 6 7 8 9 s2 b[2] b[1] b[0] s1 4 5 b 1 2 3 a main frame 5 6 7 8 args null