Transcript
Page 1: Java Virtual Machine, Call stack, Java Byte Code

JVM 및 Call Stack

Page 2: Java Virtual Machine, Call stack, Java Byte Code

학습 목표Java Virtual Machine 의 메모리 관리

자바 바이트 코드 읽기

Page 3: Java Virtual Machine, Call stack, Java Byte Code

JVM 개요

Page 4: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Operating System

Java Threads

Execution Engine

Run-time Data Area

Garbage Collector

Java Application

JavaAPI

Native Method Librarie

s

Java Virtual Machine

Page 5: Java Virtual Machine, Call stack, Java Byte Code

Verify

Link

Prepare

Class Load

Resolve Initialize

ByteCode

ByteCode

Class File

Memory

Class Loader

Page 6: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Runtime Data Areas

PC Registers

JVM Stacks

Java API Execution EngineJava Class

Files

Native Method Libraries

Method Area Heap Native

Method Stacks

JVM 은 Class Loader 를 활용해 컴파일한 Byte Code 를 Runtime Data Areas 의 Method Area 에

실행 가능한 상태로 Load 한다 .

Page 7: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Operating System

Java Threads

Execution Engine

Run-time Data Area

Garbage Collector

Java Application

JavaAPI

Native Method Librarie

s

Execution Engine

Page 8: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Runtime Data Areas

PC Registers

JVM Stacks

Java API Execution EngineJava Class

Files

Native Method Libraries

Method Area Heap Native

Method Stacks

JVM 의 Execution Engine 은 Method Area 에 Load 되어 있는 Byte Code 정보를

활용해 자바 프로그램을 실행한다 .

Execution Engine 은 ByteCode 를 한 라인씩 실행 (interpreting 방식 ) 한다 .

Page 9: Java Virtual Machine, Call stack, Java Byte Code

Method Area

모든 Thread 들이 공유하는 메모리 영역이다 .

자바 프로그램을 실행하기 위한 Class(Type), Method, Field 정보를 가진다 .

프로그램에서 공유할 필요가 있는 정보를 가진다 .

Page 10: Java Virtual Machine, Call stack, Java Byte Code

Method Area

모든 Thread 들이 공유하는 메모리 영역이다 .

Method Area 에 저장되는 정보

Type Information : 클래스와 관련한 모든 정보

Constant Pool : 문자열 상수와 같은 리터럴 상수 , Symbolic Reference

Field Information : Field 이름 , Data Type, Modifier 등

Method Information : Method 이름 , 입출력 DataType, Modifier 등

Class Variables : static 으로 선언되는 모든 클래스 변수

Reference to Class Class Loader : 특정 Type 을 Load 한 ClassLoader 정보를 관리

Reference to Class class

Method Table : Class 의 Method 에 대한 Direct Reference 를 가진다 .

Page 11: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Runtime Data Areas

PC Registers

JVM Stacks

Java API Execution EngineJava Class

Files

Native Method Libraries

Method Area Heap Native

Method Stacks

Method Area 의 Byte Code 정보를 활용해 프로그램을 실행할 때는 JVM Stacks, Native

Method Stacks 공간을 활용한다 .

Page 12: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks, Native Method Stacks

각 Thread 마다 서로 다른 메모리가 할당된다 .

Thread 가 시작할 때 생성된다 .

각 Thread 마다 서로 다른 메모리를 사용하기 때문에 여러 명의 사용자가 동시에 같은 method 에

접근해도 문제가 발생하지 않는다 .

Page 13: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Runtime Data Areas

PC Registers

JVM Stacks

Java API Execution EngineJava Class

Files

Native Method Libraries

Method Area Heap Native

Method Stacks

JVM 은 Heap 에서 자바 프로그램을 실행할 때 자바 클래스의 인스턴스와 Array 에 대한 메모리를

관리한다 .

Page 14: Java Virtual Machine, Call stack, Java Byte Code

Method Area

Thread A( 사용자 A)

JVM Stacks

main() Stack frame

Operand Stack

Local Variable

0 args

constant pool

프로그램을 실행하면 사용자마다 독립적인 JVM Stack 이 생성된다 .

JVM Stack 안에는 메서드가 호출 될 때마다 Stack Frame 이 생성된다 .

JVM Stacks

main() Stack frame

Operand Stack

Local Variable

0 args

JVM Heap

Thread B( 사용자 B)

Page 15: Java Virtual Machine, Call stack, Java Byte Code

Method Area

constant pool

JVM Heap 과 Method Area 는 Thread 가 메모리를 공유한다 .

JVM Heap

Thread B( 사용자 B)

Thread A( 사용자 A)

Page 16: Java Virtual Machine, Call stack, Java Byte Code

Method Area

constant pool

Method Area 는 클래스 ByteCode 와 변하지 않는 값이 존재하기 때문에 이슈가 없다 .

Thread 가 데이터를 공유함으로써 이슈가 있는 부분은 JVM Heap 메모리이다 .

JVM Heap

Thread B( 사용자 B)

Thread A( 사용자 A)

Page 17: Java Virtual Machine, Call stack, Java Byte Code

Heap

모든 Thread 들이 공유하는 메모리 영역이다 .

JVM 에서 대부분의 메모리 이슈가 집중되어 있는 부분이다 .

JVM 에서 Memory 가 할당 , 해제 (Garbage Collection) 의 이슈는 대부분 Heap 메모리이다 .

Page 18: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

Page 19: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

JVM Stacksmain() Stack

frameOperand

Stack

Local Variable

0 args

1. main method 실행을 위한 stack frame

생성

Page 20: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

JVM Stacksmain() Stack

frameOperand

Stack

Local Variable

0 args

1. main method 실행을 위한 stack frame

생성

2. Adder 생성자를 위한 stack frame 생성

Adder 생성자 Stack frame

Operand Stack

Local Variable

0 this

Page 21: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

JVM Stacksmain() Stack

frameOperand

Stack

Local Variable

0 args

1. main method 실행을 위한 stack frame

생성

2. Adder 생성자를 위한 stack frame 생성

3. 생성자 실행이 끝나면 Adder 생성자를

위한 stack frame 제거

Page 22: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacksmain() Stack

frameOperand

Stack

Local Variable

0 args

1. main method 실행을 위한 stack

frame 생성

2. Adder 생성자를 위한 stack frame 생성

3. 생성자 실행이 끝나면 Adder 생성자를

위한 stack frame 제거

4. add method 를 위한 stack frame 생성

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

add method Stack frame

Operand Stack

Local Variable

0 this

51

22

Page 23: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacksmain() Stack

frameOperand

Stack

Local Variable

0 args

1. main method 실행을 위한 stack

frame 생성

2. Adder 생성자를 위한 stack frame

생성

3. 생성자 실행이 끝나면 Adder 생성자를

위한 stack frame 제거

4. add method 를 위한 stack frame 생성

5. add method 에 대한 stack frame 제거

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

Page 24: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks

1. main method 실행을 위한 stack

frame 생성

2. Adder 생성자를 위한 stack frame

생성

3. 생성자 실행이 끝나면 Adder 생성자를

위한 stack frame 제거

4. add method 를 위한 stack frame

생성

5. add method 에 대한 stack frame

제거

6. main method 에 대한 stack frame

제거

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

Page 25: Java Virtual Machine, Call stack, Java Byte Code

자바 바이트 코드 읽기

Page 26: Java Virtual Machine, Call stack, Java Byte Code

Execution Engine

컴파일한 바이트 코드를 한 라인씩 읽어내려가면서 자바 프로그램을 실행한다 .

Page 27: Java Virtual Machine, Call stack, Java Byte Code

javap –c HelloWorld.class

public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}

D:\next-workspace\workspace\java\bin>javap -c HelloWorld.classCompiled from "HelloWorld.java"public class HelloWorld { public HelloWorld(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22 // String Hello World! 5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return}

Page 28: Java Virtual Machine, Call stack, Java Byte Code

D:\next-workspace\workspace\java\bin>javap -verbose HelloWorld.classClassfile /D:/next-workspace/workspace/java/bin/HelloWorld.class Last modified 2013. 3. 20; size 534 bytes MD5 checksum 77129a8bac38a3ac8dc870dd7362668c Compiled from "HelloWorld.java"public class HelloWorld SourceFile: "HelloWorld.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Class #2 // HelloWorld #2 = Utf8 HelloWorld #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Utf8 Code #8 = Methodref #3.#9 // java/lang/Object."<init>":()V #9 = NameAndType #5:#6 // "<init>":()V #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 LHelloWorld; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Fieldref #17.#19 // java/lang/System.out:Ljava/io/PrintStream; #17 = Class #18 // java/lang/System #18 = Utf8 java/lang/System #19 = NameAndType #20:#21 // out:Ljava/io/PrintStream; #20 = Utf8 out #21 = Utf8 Ljava/io/PrintStream; #22 = String #23 // Hello World! #23 = Utf8 Hello World! #24 = Methodref #25.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V #25 = Class #26 // java/io/PrintStream #26 = Utf8 java/io/PrintStream #27 = NameAndType #28:#29 // println:(Ljava/lang/String;)V #28 = Utf8 println #29 = Utf8 (Ljava/lang/String;)V #30 = Utf8 args #31 = Utf8 [Ljava/lang/String; #32 = Utf8 SourceFile #33 = Utf8 HelloWorld.java

javap –verbose HelloWorld.class

Page 29: Java Virtual Machine, Call stack, Java Byte Code

{ public HelloWorld(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHelloWorld;

public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #22 // String Hello World! 5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 3: 0 line 4: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String;}

Page 30: Java Virtual Machine, Call stack, Java Byte Code

Bytecode Visualizer Eclipse 플러그인 활용 (http://www.slipp.net/questions/292)

Page 31: Java Virtual Machine, Call stack, Java Byte Code

Java opcode(bytecode instruction)

http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

Page 32: Java Virtual Machine, Call stack, Java Byte Code

Pre-fix/

SuffixOperand Type

i integer

l long

s short

b byte

c character

f float

d double

z boolean

a reference

Page 33: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacksadd method Stack frame

Operand Stack

Local Variable

0 this

51

22

load opcode

Local Variable 영역의 값을 Operand Stack 영역으로 복사하는 명령어(instruction)

JVM Stacksadd method Stack frame

Operand Stack

Local Variable

0 this

51

22

iload_1 실행 후

50

Page 34: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacksmain method Stack frame

Operand Stack

Local Variable

0 this

adder1

store opcode

Operand Stack 영역의 값을 Local Variable 영역으로 이동하는 명령어(instruction)

istore_2 실행 후

70

JVM Stacksmain method Stack frame

Operand Stack

Local Variable

0 this

adder1

72

Page 35: Java Virtual Machine, Call stack, Java Byte Code

invoke* opcode : 생성자 , method 를 호출할 때

사용하는 opcode

• invokestatic : 클래스 (static) method 를 호출

• invokeinterface : interface method 를 호출

• invokespecial : 생성자 또는 인스턴스 method( 다형성 X) 호출

• Invokevirtual : 인스턴스 method 를 호출 ( 다형성 O)

Page 36: Java Virtual Machine, Call stack, Java Byte Code

public class StringConcatenations { public String concat1(String start, String end) { return start + end; } public void concat2(StringBuffer start, String end) { start.append(end); }}

Case 1

Page 37: Java Virtual Machine, Call stack, Java Byte Code

public class StringLiterals { public static void main(String[] args) { String one = "Test"; String two = "Test"; String three = "T" + "e" + "s" + "t"; String four = new String("Test"); }}

Case 2

Page 38: Java Virtual Machine, Call stack, Java Byte Code

Case 2

Page 39: Java Virtual Machine, Call stack, Java Byte Code

public class MyFor { public int sum(int[] values) { int sum = 0; for (int i = 0; i < values.length; i++) { sum +=- values[i]; } return sum; }}

Case 3

Page 40: Java Virtual Machine, Call stack, Java Byte Code

Execution Engine Simulation1

Page 41: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); System.out.println(result); }}

Page 42: Java Virtual Machine, Call stack, Java Byte Code

D:\next-workspace\workspace\java\bin>javap -c net/slipp/AdderCompiled from "Adder.java"public class net.slipp.Adder { public net.slipp.Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return

int add(int, int); Code: 0: iload_1 1: iload_2 2: iadd 3: ireturn

public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup 4: invokespecial #21 // Method "<init>":()V 7: astore_1 8: aload_1 9: iconst_5 10: iconst_2 11: invokevirtual #22 // Method add:(II)I 14: istore_2 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_2 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 22: return}

Page 43: Java Virtual Machine, Call stack, Java Byte Code

D:\next-workspace\workspace\java\bin>javap -c Adder.classCompiled from "Adder.java"public class Adder { public Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return

int add(int, int); Code: 0: iload_1 1: iload_2 2: iadd 3: ireturn

public static void main(java.lang.String[]); Code: 0: new #1 // class Adder 3: dup 4: invokespecial #21 // Method "<init>":()V 7: astore_1 8: aload_1 9: iconst_5 10: iconst_2 11: invokevirtual #22 // Method add:(II)I 14: istore_2 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_2 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 22: return}

Execution Engine 은 interpreting 방식으로 한번에 한 라인씩 실행한다 .

한 라인을 instruction 이라고 한다 .

instruction 은 offset, opcode(operation code), 피연산자 (operand) 로 구성된다 .

Page 44: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

JVM 은 Method Area 에 저장되어 있는 Bytecode 를 interpreting 방식으로 읽어 실행해 나간다 . 먼저 Adder 의 main() 가 Entry Point 가 된다 .

main() Stack frame

Operand Stack

Local Variable

0 args

Page 45: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder

Method Area 에 있는 Adder 정보를 활용해 Heap 메모리에 Adder Instance 를 생성한 후 Operand Stack 0 에 Adder Instance 에 대한 reference 를 저장

Adder Instance

adder0

Method Area

Page 46: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup

Operand Stack 0 에 Adder Instance 에 대한 reference 를 Operand Stack 1 에 복사한다 .

Adder Instance

adder0

adder1

Method Area

Page 47: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: 3: dup 4: invokespecial #21 // Method "<init>":()V

Adder 클래스의 기본 생성자 (Object 기본 생성자 ) 를 호출한다 . Adder 기본 생성자 Stack Frame 이 생성된다 .

Adder Instance

adder0

Adder 생성자 Stack frame

Operand Stack

Local Variable

0 this

Method Area

Page 48: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public net.slipp.Adder(); Code: 0: aload_0

Adder 생성자 Stack Frame 의 Local Variable의 index 0 의 값을 Operand Stack 으로 로드한다 .

Adder Instance

adder0

Adder 생성자 Stack frame

Operand Stack

Local Variable

0 this

this0

Method Area

Page 49: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public net.slipp.Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V

Adder Instance 에 대한 실질적인 초기화가 이 단계에서 진행된다 .

초기화가 완료된 Adder Instance

adder0

Adder 생성자 Stack frame

Operand Stack

Local Variable

0 this

Method Area

Page 50: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public net.slipp.Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return

Adder 기본 생성자에 대한 Stack Frame 이 JVM Stack 에서 제거된다 .

adder0

초기화가 완료된 Adder Instance

Method Area

Page 51: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 4: invokespecial #21 // Method "<init>":()V 7: astore_1

Operand Stack 에서 pop 한 결과를 Local Variable 의 index 1 번에 저장한다 .

adder1

초기화가 완료된 Adder Instance

Method Area

Page 52: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 7: astore_1 8: aload_1

Variable 의 index 1 번에 저장된 값을 Operand Stack 에 push 한다 .

adder1

초기화가 완료된 Adder Instance

adder0

Method Area

Page 53: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 8: aload_1 9: iconst_5

Method Area 의 constant pool 에 존재하는 상수 값 5 를 Operand Stack 에 push 한다 .

adder1

초기화가 완료된 Adder Instance

adder0

1

constant pool

2

51

5

Method Area

Page 54: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 9: iconst_5 10: iconst_2

Method Area 의 constant pool 에 존재하는 상수 값 2 를 Operand Stack 에 push 한다 .

adder1

초기화가 완료된 Adder Instance

adder0

1

constant pool

2

51

5

22

Page 55: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 10: iconst_2 11: invokevirtual #22 // Method add:(II)I

add() 메소드에 대한 Stack frame 을 JVM Stack 에 push 하고 main() 메소드의 operand stack 의 값을 add() 메소드에 복사한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

Method Area

Page 56: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

int add(int, int); Code: 0: iload_1

add() 메소드 Stack Frame 의 Local Variable의 index 1 번 값을 Operand Stack 에 push한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

50

Method Area

Page 57: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

int add(int, int); Code: 0: iload_1 1: iload_2

add() 메소드 Stack Frame 의 Local Variable의 index 2 번 값을 Operand Stack 에 push한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

50

21

Method Area

Page 58: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

int add(int, int); Code: 0: iload_1 1: iload_2 2: iadd

Operand Stack 의 인자를 iadd 에 전달해 덧셈을 실행한다 . 실행한 결과를 Operand Stack 에 저장한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

70

Method Area

Page 59: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

int add(int, int); Code: […] 2: iadd 3: ireturn

add() Stack Frame 의 operand stack 값을 main() 메소드로 복사하고 add() Stack Frame을 pop 한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

5

70

Method Area

Page 60: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

Operand Stack 값을 pop 해서 Local Variable의 index 2 번에 저장한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

572

public static void main(java.lang.String[]); Code: […] 11: invokevirtual #22 // Method add:(II)I 14: istore_2

Method Area

Page 61: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

PrintStream 에 대한 reference 를 얻어 operand stack index 0 에 저장한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

572

public static void main(java.lang.String[]); Code: […] 14: istore_2 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream;

PrintStream Instance

out0

Method Area

class variables

Page 62: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

Local Variable index 2 값을 operand stack에 push 한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

572

public static void main(java.lang.String[]); Code: […] 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_2

out0

71

Method Area

PrintStream Instance

class variables

Page 63: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

PrintStream 인스턴스의 println() 메소드에 operand 값을 인자로 전달한다 .

adder1

초기화가 완료된 Adder Instance

1

constant pool

2

572

public static void main(java.lang.String[]); Code: […] 18: iload_2 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V

Method Area

PrintStream Instance

class variables

println() Stack frame

Operand Stack

Local Variable

this0

71

Page 64: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

애플리케이션을 종료한다 .

1

constant pool

2

5

public static void main(java.lang.String[]); Code: […] 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 22: return

시간이 지나면 Garbage Collector 에 의해 GC 대상이 된다 .

초기화가 완료된 Adder Instance

Method Area

PrintStream Instance

class variables

Page 65: Java Virtual Machine, Call stack, Java Byte Code

Execution Engine Simulation2

Page 66: Java Virtual Machine, Call stack, Java Byte Code

package net.slipp;

public class Adder { private int i; private int j;

Adder(int i, int j) { this.i = i; this.j = j; }

public int add() { return i + j; }

public static void main(String[] args) { Adder adder = new Adder(5, 2); int result = adder.add(); System.out.println(result); }}

Page 67: Java Virtual Machine, Call stack, Java Byte Code

D:\next-workspace\workspace\java\bin>javap -c net/slipp/AdderCompiled from "Adder.java"public class net.slipp.Adder { net.slipp.Adder(int, int); Code: 0: aload_0 1: invokespecial #11 // Method java/lang/Object."<init>":()V 4: aload_0 5: iload_1 6: putfield #14 // Field i:I 9: aload_0 10: iload_2 11: putfield #16 // Field j:I 14: return

public int add(); Code: 0: aload_0 1: getfield #14 // Field i:I 4: aload_0 5: getfield #16 // Field j:I 8: iadd 9: ireturn

public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup 4: iconst_5 5: iconst_2 6: invokespecial #26 // Method "<init>":(II)V 9: astore_1 10: aload_1 11: invokevirtual #28 // Method add:()I 14: istore_2 15: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_2 19: invokevirtual #36 // Method java/io/PrintStream.println:(I)V 22: return}

Page 68: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup

Adder Instance

adder0

adder1

Page 69: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 4: iconst_5 5: iconst_2

adder1

Adder Instance

adder0

1

constant pool

2

51

5

22

Method Area

Page 70: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public static void main(java.lang.String[]); Code: […] 4: iconst_5 5: iconst_2 6: invokespecial #26 // Method "<init>":(II)V

adder1

Adder Instance

1

constant pool

2

5

Adder 생성자 Stack frame

Operand Stack

Local Variable

adder0

51

22

Method Area

Page 71: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

net.slipp.Adder(int, int); Code: […] 4: aload_0 5: iload_1

adder1

Adder Instance

1

constant pool

2

5

Adder 생성자 Stack frame

Operand Stack

Local Variable

adder0

51

22

adder0

51

Method Area

Page 72: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

net.slipp.Adder(int, int); Code: […] 5: iload_1 6: putfield #14 // Field i:I

adder1

1

constant pool

2

5

Adder 생성자 Stack frame

Operand Stack

Local Variable

adder0

51

22

Adder Instance

int i = 5

Method Area

Page 73: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

net.slipp.Adder(int, int); Code: […] 9: aload_0 10: iload_2 11: putfield #16 // Field j:I

adder1

1

constant pool

2

5

Adder 생성자 Stack frame

Operand Stack

Local Variable

adder0

51

22

Adder Instance

int i = 5int j = 2

Method Area

Page 74: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

public int add(); Code: 0: aload_0 1: getfield #14 // Field i:I 4: aload_0 5: getfield #16 // Field j:I

adder1

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

adder0

초기화가 완료된 Adder Instance

int i = 5int j = 2

adder0

51

22

Method Area

Page 75: Java Virtual Machine, Call stack, Java Byte Code

나머지 과정은 Simulation1 과 비슷하다 .

Page 76: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks vs Heap

Page 77: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

adder1

Adder Instance

1

constant pool

2

5

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

50

21

Method Area

Page 78: Java Virtual Machine, Call stack, Java Byte Code

public class Adder { int add(int i, int j) { return i + j; }}

JVM Stacksmain() Stack frame

Operand Stack

Local Variable

0 args

adder1

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

50

21

사용자 1 = Thread 1

JVM Stacksmain() Stack frame

Operand Stack

Local Variable

0 args

adder1

add() Stack frame

Operand Stack

Local Variable

0 adder

51

22

50

21

사용자 2 = Thread 2

Page 79: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

adder1

1

constant pool

2

5

Adder Instance

int i = 5int j = 2

Method Area

Page 80: Java Virtual Machine, Call stack, Java Byte Code

JVM Heap

Adder Instance

int i = 5int j = 2

사용자 1 = Thread 1

사용자 2 = Thread 2

public class Adder { private int i; private int j;

Adder(int i, int j) { this.i = i; this.j = j; }}

Page 81: Java Virtual Machine, Call stack, Java Byte Code

Class Loader System

Runtime Data Areas

PC Registers

JVM Stacks

Java API Execution EngineJava Class

Files

Native Method Libraries

Method Area Heap Native

Method Stacks

JVM 의 Stacks 영역은 Thread 별로 ( 사용자 ) 생성된다 . 따라서 각 Stacks 영역 사이에는 영향을 미치지 않는다 . 이를 Thread Safe 하다고 한다 .

JVM 의 Heap 영역은 모든 Thread 가 공유한다 . 따라서 Heap 에 존재하는 Object 의 상태 값은 Thread 사이에 영향을 받는다 . 이를 Thread Safe 하지 않다고 한다 .

Page 82: Java Virtual Machine, Call stack, Java Byte Code

public class Adder { int add(int i, int j) { return i + j; } public static void main(String[] args) { Adder adder = new Adder(); int result = adder.add(5,2); }}

사용자 1 = Thread 1

사용자 2 = Thread 2

Adder 는 Heap 영역에서 관리하는 상태 값은 없다 . 모든 값은 각 Thread 별로 생성되는 Stacks 에서 관리한다 .

위 Adder 클래스는 Heap 영역에 인스턴스 하나를 생성한 후 모든 Thread 에서 재사용할 수 있다 .

Page 83: Java Virtual Machine, Call stack, Java Byte Code

public class Adder { private int i; private int j;

Adder(int i, int j) { this.i = i; this.j = j; }

public int add() { return i + j; }

public static void main(String[] args) { Adder adder = new Adder(5, 2); int result = adder.add(); System.out.println(result); }}

사용자 1 = Thread 1

사용자 2 = Thread 2

Adder 는 Heap 영역에서 i, j 에 대한 상태 값을 관리하고 있다 . 즉 , Thread Safe 하지 않다 .

위 Adder 클래스는 각 Thread 별로 독립적으로 실행하려면 매번 인스턴스를 생성해야 한다 .

Page 84: Java Virtual Machine, Call stack, Java Byte Code

Call by value 와 Call by reference

Page 85: Java Virtual Machine, Call stack, Java Byte Code

public class Calculator { int add(int i, int j) { i = 5; j = 3; return i + j; }

public static void main(String[] args) { Calculator calculator = new Calculator(); int i = 3; int j = 2; System.out.println("before i : " + i); System.out.println("before j : " + j);

calculator.add(i, j);

System.out.println("after i : " + i); System.out.println("after j : " + j); }}

Page 86: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

calculator1

초기화가 완료된 Calculator Instanceadd() Stack frame

Operand Stack

Local Variable

3

2

2

3

public static void main(String[] args) { Calculator calculator = new Calculator(); int i = 3; int j = 2; calculator.add(i, j);}

Page 87: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

calculator1

초기화가 완료된 Calculator Instanceadd() Stack frame

Operand Stack

Local Variable

0 calculator

31

223

2

2

3

int add(int i, int j) { i = 5; j = 3; return i + j;}

Page 88: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

calculator1

초기화가 완료된 Calculator Instanceadd() Stack frame

Operand Stack

Local Variable

0 calculator

51

323

2

2

3

int add(int i, int j) { i = 5; j = 3; return i + j;}

Page 89: Java Virtual Machine, Call stack, Java Byte Code

Call by value

자바의 기본 자료형 (primitive type) 은 call by value 에 의해서 동작한다 .

즉 , 메소드를 호출할 때 전달되는 인자의 값이 복사된다 .

Page 90: Java Virtual Machine, Call stack, Java Byte Code

public class Student { String name; public Student(String name) { this.name = name; }}

public class MessageRenderer { public void callByReference(Student student) { student.name = " 예은 "; } public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }}

Case 1

Page 91: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

Page 92: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

public void callByReference(Student student) { student.name = " 예은 ";}

student0

Page 93: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 예은” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

public void callByReference(Student student) { student.name = " 예은 ";}

student0

Page 94: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 예은” Student Instance

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

Page 95: Java Virtual Machine, Call stack, Java Byte Code

public class Student { String name; public Student(String name) { this.name = name; }}

public class MessageRenderer { public void callByReference(Student student) { student = new Student(" 예은 "); } public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }}

Case 2

Page 96: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 2public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

Page 97: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

public void callByReference(Student student) { student = new Student(“ 예은” );}

student0

Page 98: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

callByReference() Stack frame

Operand Stack

Local Variable

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

public void callByReference(Student student) { student = new Student(“ 예은” );}

student0

name = “ 예은” Student Instance

Page 99: Java Virtual Machine, Call stack, Java Byte Code

JVM Stacks Method Area

JVM Heap

main() Stack frame

Operand Stack

Local Variable

0 args

student1

name = “ 주한” Student Instance

Case 1public static void main(String[] args) { Student student = new Student(" 주한 "); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name);}

Page 100: Java Virtual Machine, Call stack, Java Byte Code

Call by reference

자바의 모든 객체 ( 인스턴스 ) 는 call by reference 에 의해서 동작한다 .

즉 , 메소드를 호출할 때 전달되는 인자는 값이 아니라 참조하고 있는 주소 값이 전달된다 .

Page 101: Java Virtual Machine, Call stack, Java Byte Code

참고 문서


Top Related