Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리 6.4 배열과 메모리
6.1 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 메소드의 매개변수, 지역변수 등을 저장
6.2 프로그램 실행과 메모리 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
6.3 객체생성과 메모리 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
6.4 배열과 메모리 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