SlideShare una empresa de Scribd logo
1 de 101
JVM 및 Call Stack
학습 목표 
Java Virtual Machine의 메모리 관리 
자바 바이트 코드 읽기
JVM 개요
Java Virtual Machine 
Class Loader System 
Operating System 
Java Threads 
Execution 
Engine 
Run-time 
Data Area 
Garbage 
Collector 
Java Application 
Java 
API 
Native 
Method 
Libraries
ByteCode 
Link 
Verify 
Prepare 
Class 
Load 
Class Loader 
Resolve Initialize 
ByteCode 
Class File 
Memory
Java API Execution 
Class Loader 
Engine Java Class 
System 
Runtime Data Areas 
PC 
Registers 
JVM 
Stacks 
Files 
Native 
Method 
Libraries 
Method 
Area 
Heap Native 
Method 
Stacks 
JVM은 Class Loader를 활용해 컴파일한 Byte Code를 Runtime Data Areas의 Method Area에 실행 
가능한 상태로 Load한다.
Execution Engine 
Class Loader System 
Operating System 
Java 
Threads 
Execution 
Engine 
Run-time 
Data Area 
Garbage 
Collector 
Java Application 
Java 
API 
Native 
Method 
Libraries
Java API Execution 
Class Loader 
Engine Java Class 
System 
Runtime Data Areas 
PC 
Registers 
JVM 
Stacks 
Files 
Native 
Method 
Libraries 
Method 
Area 
Heap Native 
Method 
Stacks 
JVM의 Execution Engine은 Method Area에 Load되어 있는 Byte Code 정보를 활용해 자바 
프로그램을 실행한다. 
Execution Engine은 ByteCode를 한 라인씩 실행(interpreting 방식)한다.
Method Area 
모든 Thread 들이 공유하는 메모리 영역이다. 
자바 프로그램을 실행하기 위한 Class(Type), Method, Field 정보를 가진다. 
프로그램에서 공유할 필요가 있는 정보를 가진다.
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를 가진다.
Java API Execution 
Class Loader 
Engine Java Class 
System 
Runtime Data Areas 
PC 
Registers 
JVM 
Stacks 
Files 
Native 
Method 
Libraries 
Method 
Area 
Heap Native 
Method 
Stacks 
Method Area의 Byte Code 정보를 활용해 프로그램을 실행할 때는 JVM Stacks, Native Method 
Stacks 공간을 활용한다.
JVM Stacks, Native Method Stacks 
각 Thread마다 서로 다른 메모리가 할당된다. 
Thread가 시작할 때 생성된다. 
각 Thread마다 서로 다른 메모리를 사용하기 때문에 여러 명의 사용자가 동시에 같은 method에 
접근해도 문제가 발생하지 않는다.
Java API Execution 
Class Loader 
Engine Java Class 
System 
Runtime Data Areas 
PC 
Registers 
JVM 
Stacks 
Files 
Native 
Method 
Libraries 
Method 
Area 
Heap Native 
Method 
Stacks 
JVM은 Heap에서 자바 프로그램을 실행할 때 자바 클래스의 인스턴스와 Array에 대한 메모리를 
관리한다.
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)
JVM Heap과 Method Area는 Thread가 메모리를 공유한다. 
Method 
Area 
constant 
pool 
JVM Heap 
Thread A 
(사용자 A) 
Thread B 
(사용자 B)
Method Area는 클래스 ByteCode와 변하지 않는 값이 존재하기 때문에 이슈가 없다. 
Thread가 데이터를 공유함으로써 이슈가 있는 부분은 JVM Heap 메모리이다. 
Method 
Area 
constant 
pool 
JVM Heap 
Thread A 
(사용자 A) 
Thread B 
(사용자 B)
Heap 
모든 Thread 들이 공유하는 메모리 영역이다. 
JVM에서 대부분의 메모리 이슈가 집중되어 있는 부분이다. 
JVM에서 Memory가 할당, 해제(Garbage Collection)의 이슈는 대부분 Heap 메모리이다.
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); 
} 
}
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 Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
1. 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); 
} 
} 
JVM Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
1. main method 실행을 위한 stack frame 
생성 
2. Adder 생성자를 위한 stack frame 생성 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
0 this
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 Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
1. main method 실행을 위한 stack frame 
생성 
2. Adder 생성자를 위한 stack frame 생성 
3. 생성자 실행이 끝나면 Adder 생성자를 
위한 stack frame 제거
JVM Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
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); 
} 
1. main method 실행을 위한 stack frame 
생성 
2. Adder 생성자를 위한 stack frame 생성 
3. 생성자 실행이 끝나면 Adder 생성자를 
위한 stack frame 제거 
4. add method를 위한 stack frame 생성 
} 
add method 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 this
JVM Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
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); 
} 
1. main method 실행을 위한 stack frame 
생성 
2. Adder 생성자를 위한 stack frame 생성 
3. 생성자 실행이 끝나면 Adder 생성자를 
위한 stack frame 제거 
4. add method를 위한 stack frame 생성 
5. add method에 대한 stack frame 제거 
}
JVM Stacks 
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); 
} 
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 제거 
}
자바 바이트 코드 읽기
Execution Engine 
컴파일한 바이트 코드를 한 라인씩 읽어내려가면서 자바 프로그램을 실행한다.
public class HelloWorld { 
public static void main(String[] args) { 
System.out.println("Hello World!"); 
} 
javap –c HelloWorld.class 
} 
D:next-workspaceworkspacejavabin>javap -c HelloWorld.class 
Compiled 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 
}
D:next-workspaceworkspacejavabin>javap -verbose HelloWorld.class 
Classfile /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_SUPER 
Constant pool: 
javap –verbose HelloWorld.class 
#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
{ 
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; 
}
Bytecode Visualizer Eclipse 플러그인 활용 
(http://www.slipp.net/questions/292)
Java opcode(bytecode instruction) 
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
Prefix/ 
Suffix 
Operand Type 
i integer 
l long 
s short 
b byte 
c character 
f float 
d double 
z boolean 
a reference
JVM Stacks 
add method 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 this 
load opcode 
Local Variable 영역의 값을 
Operand Stack 영역으로 
복사하는 
명령어(instruction) 
JVM Stacks 
add method 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 this 
iload_1 
실행 후 
0 5
JVM Stacks 
main method 
Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 this 
store opcode 
Operand Stack 영역의 값을 
Local Variable 영역으로 
이동하는 
명령어(instruction) 
istore_2 
실행 후 
0 7 
JVM Stacks 
main method 
Stack frame 
Operand Stack 
Local Variable 
2 7 
1 adder 
0 this
invoke* opcode : 생성자, method를 호출할 때 사용하는 
opcode 
• invokestatic : 클래스(static) method를 호출 
• invokeinterface : interface method를 호출 
• invokespecial : 생성자 또는 인스턴스 method(다형성 X) 호출 
• Invokevirtual : 인스턴스 method를 호출(다형성 O)
Case 1 
public class StringConcatenations { 
public String concat1(String start, String end) { 
return start + end; 
} 
public void concat2(StringBuffer start, String end) { 
start.append(end); 
} 
}
Case 2 
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
Case 3 
public class MyFor { 
public int sum(int[] values) { 
int sum = 0; 
for (int i = 0; i < values.length; i++) { 
sum +=- values[i]; 
} 
return sum; 
} 
}
Execution Engine Simulation1
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); 
} 
}
D:next-workspaceworkspacejavabin>javap -c net/slipp/Adder 
Compiled 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 
}
D:next-workspaceworkspacejavabin>javap -c Adder.class 
Compiled 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)로 
구성된다.
JVM Stacks Method 
Area 
JVM Heap 
JVM은 Method Area에 저장되어 있는 Bytecode를 interpreting 방식으로 읽어 
실행해 나간다. 먼저 Adder의 main()가 Entry Point가 된다. 
main() Stack frame 
Operand Stack 
Local Variable 
0 args
public static void main(java.lang.String[]); 
Code: 
0: new #1 // class net/slipp/Adder 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Method Area에 있는 Adder 정보를 활용해 Heap 
메모리에 Adder Instance를 생성한 후 Operand Stack 
0에 Adder Instance에 대한 reference를 저장 
Adder Instance 
0 adder 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
0: new #1 // class net/slipp/Adder 
3: dup 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
1 adder 
Local Variable 
0 args 
Operand Stack 0에 Adder Instance에 대한 
reference를 Operand Stack 1에 복사한다. 
Adder Instance 
0 adder 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
3: dup 
4: invokespecial #21 // Method "<init>":()V 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Adder 클래스의 기본 생성자(Object 기본 
생성자)를 호출한다. Adder 기본 생성자 Stack 
Frame이 생성된다. 
Adder Instance 
0 adder 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
0 this 
Method 
Area
public net.slipp.Adder(); 
Code: 
0: aload_0 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Adder 생성자 Stack Frame의 Local Variable의 
index 0의 값을 Operand Stack으로 로드한다. 
Adder Instance 
0 adder 
Adder 생성자 
Stack frame 
Operand Stack 
0 this 
Local Variable 
0 this 
Method 
Area
public net.slipp.Adder(); 
Code: 
0: aload_0 
1: invokespecial #8 // Method java/lang/Object."<init>":()V 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Adder Instance에 대한 실질적인 초기화가 이 
단계에서 진행된다. 
초기화가 완료된 
Adder Instance 
0 adder 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
0 this 
Method 
Area
public net.slipp.Adder(); 
Code: 
0: aload_0 
1: invokespecial #8 // Method java/lang/Object."<init>":()V 
4: return 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Adder 기본 생성자에 대한 Stack Frame이 JVM 
Stack에서 제거된다. 
0 adder 
초기화가 완료된 
Adder Instance 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
4: invokespecial #21 // Method "<init>":()V 
7: astore_1 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Operand Stack에서 pop한 결과를 Local 
Variable의 index 1번에 저장한다. 
1 adder 
초기화가 완료된 
Adder Instance 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
7: astore_1 
8: aload_1 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Variable의 index 1번에 저장된 값을 Operand 
Stack에 push한다. 
1 adder 
초기화가 완료된 
Adder Instance 
0 adder 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
8: aload_1 
9: iconst_5 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Method Area의 constant pool에 존재하는 상수 
값 5를 Operand Stack에 push한다. 
1 adder 
초기화가 완료된 
Adder Instance 
0 adder 
Method 
Area 
constant 
pool 
1 
2 
… 
1 5 
5
public static void main(java.lang.String[]); 
Code: 
[…] 
9: iconst_5 
10: iconst_2 
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Method Area의 constant pool에 존재하는 상수 
값 2를 Operand Stack에 push한다. 
1 adder 
초기화가 완료된 
Adder Instance 
0 adder 
constant 
pool 
1 
2 
… 
1 5 
5 
2 2
public static void main(java.lang.String[]); 
Code: 
[…] 
10: iconst_2 
11: invokevirtual #22 // Method add:(II)I 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
add() 메소드에 대한 Stack frame을 JVM Stack에 
push하고 main() 메소드의 operand stack의 값을 
add() 메소드에 복사한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
add() Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
int add(int, int); 
Code: 
0: iload_1 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
add() 메소드 Stack Frame의 Local Variable의 
index 1번 값을 Operand Stack에 push한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
add() Stack frame 
Operand Stack 
0 5 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
int add(int, int); 
Code: 
0: iload_1 
1: iload_2 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
add() 메소드 Stack Frame의 Local Variable의 
index 2번 값을 Operand Stack에 push한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
add() Stack frame 
Operand Stack 
1 2 
0 5 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
int add(int, int); 
Code: 
0: iload_1 
1: iload_2 
2: iadd 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Operand Stack의 인자를 iadd에 전달해 덧셈을 
실행한다. 실행한 결과를 Operand Stack에 
저장한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
add() Stack frame 
Operand Stack 
0 7 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
int add(int, int); 
Code: 
[…] 
2: iadd 
3: ireturn 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
add() Stack Frame의 operand stack 값을 main() 
메소드로 복사하고 add() Stack Frame을 
pop한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
0 7 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
11: invokevirtual #22 // Method add:(II)I 
14: istore_2 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
Operand Stack 값을 pop해서 Local Variable의 
index 2번에 저장한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
2 7 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
14: istore_2 
15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
PrintStream에 대한 reference를 얻어 operand 
stack index 0에 저장한다. 
1 adder 
초기화가 완료된 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
2 7 
PrintStream 
Instance 
0 out 
Method 
Area 
class 
variables
public static void main(java.lang.String[]); 
Code: 
[…] 
15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 
18: iload_2 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
1 7 
0 out 
Local Variable 
0 args 
Local Variable index 2 값을 operand stack에 
push 한다. 
1 adder 
초기화가 완료된 
Adder Instance 
class 
variables 
constant 
pool 
1 
2 
… 
5 
2 7 
Method 
Area 
PrintStream 
Instance
public static void main(java.lang.String[]); 
Code: 
[…] 
18: iload_2 
19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
0 args 
PrintStream 인스턴스의 println() 메소드에 
operand 값을 인자로 전달한다. 
1 adder 
초기화가 완료된 
Adder Instance 
class 
variables 
constant 
pool 
1 
2 
… 
5 
2 7 
Method 
Area 
PrintStream 
Instance 
println() Stack frame 
Operand Stack 
Local Variable 
1 7 
0 this
애플리케이션을 종료한다. 
JVM Stacks JVM Heap 
class 
variables 
constant 
pool 
1 
2 
… 
5 
public static void main(java.lang.String[]); 
Code: 
[…] 
19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 
22: return 
초기화가 완료된 
Adder Instance 
시간이 지나면 Garbage 
Collector에 의해 GC 
대상이 된다. 
Method 
Area 
PrintStream 
Instance
Execution Engine Simulation2
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); 
} 
}
D:next-workspaceworkspacejavabin>javap -c net/slipp/Adder 
Compiled 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 
}
public static void main(java.lang.String[]); 
Code: 
0: new #1 // class net/slipp/Adder 
3: dup 
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
1 adder 
Local Variable 
0 args 
Adder Instance 
0 adder
public static void main(java.lang.String[]); 
Code: 
[…] 
4: iconst_5 
5: iconst_2 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
Adder Instance 
0 adder 
constant 
pool 
1 
2 
… 
1 5 
5 
2 2 
Method 
Area
public static void main(java.lang.String[]); 
Code: 
[…] 
4: iconst_5 
5: iconst_2 
6: invokespecial #26 // Method "<init>":(II)V 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
net.slipp.Adder(int, int); 
Code: 
[…] 
4: aload_0 
5: iload_1 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
Adder Instance 
constant 
pool 
1 
2 
… 
5 
Adder 생성자 
Stack frame 
Operand Stack 
1 5 
0 adder 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
net.slipp.Adder(int, int); 
Code: 
[…] 
5: iload_1 
6: putfield #14 // Field i:I 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
constant 
pool 
1 
2 
… 
5 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 adder 
Adder Instance 
int i = 5 
Method 
Area
net.slipp.Adder(int, int); 
Code: 
[…] 
9: aload_0 
10: iload_2 
11: putfield #16 // Field j:I 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
constant 
pool 
1 
2 
… 
5 
Adder 생성자 
Stack frame 
Operand Stack 
Local Variable 
2 2 
1 5 
0 adder 
Adder Instance 
int i = 5 
int j = 2 
Method 
Area
public int add(); 
Code: 
0: aload_0 
1: getfield #14 // Field i:I 
4: aload_0 
5: getfield #16 // Field j:I 
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
constant 
pool 
1 
2 
… 
5 
add() Stack 
frame 
Operand Stack 
2 2 
1 5 
Local Variable 
0 adder 
초기화가 완료된 Adder 
Instance 
int i = 5 
int j = 2 
0 adder 
Method 
Area
나머지 과정은 Simulation1과 비슷하다.
JVM Stacks vs Heap
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
Adder Instance 
constant pool 
1 
2 
… 
5 
add() Stack frame 
Operand Stack 
1 2 
0 5 
Local Variable 
2 2 
1 5 
0 adder 
Method 
Area
public class Adder { 
int add(int i, int j) { 
return i + j; 
} 
} 
JVM Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
add() Stack frame 
Operand Stack 
1 2 
0 5 
Local Variable 
2 2 
1 5 
0 adder 
사용자 1 = Thread 1 
JVM Stacks 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
add() Stack frame 
Operand Stack 
1 2 
0 5 
Local Variable 
2 2 
1 5 
0 adder 
사용자 2 = Thread 2
JVM Stacks JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 adder 
0 args 
constant 
pool 
1 
2 
… 
5 
Adder Instance 
int i = 5 
int j = 2 
Method 
Area
JVM Heap 
Adder Instance 
int i = 5 
int 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; 
} 
}
Java API Execution 
Class Loader 
Engine Java Class 
System 
Runtime Data Areas 
PC 
Registers 
JVM 
Stacks 
Files 
Native 
Method 
Libraries 
Method 
Area 
Heap Native 
Method 
Stacks 
JVM의 Stacks 영역은 Thread 별로(사용자) 생성된다. 따라서 각 Stacks 영역 사이에는 
영향을 미치지 않는다. 이를 Thread Safe하다고 한다. 
JVM의 Heap 영역은 모든 Thread가 공유한다. 따라서 Heap에 존재하는 Object의 상태 
값은 Thread 사이에 영향을 받는다. 이를 Thread Safe하지 않다고 한다.
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에서 
재사용할 수 있다.
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별로 독립적으로 실행하려면 매번 인스턴스를 생성해야 한다.
Call by value와 Call by reference
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); 
} 
}
public static void main(String[] args) { 
Calculator calculator = new Calculator(); 
int i = 3; 
int j = 2; 
calculator.add(i, j); 
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
2 
3 
1 calculator 
0 args 
초기화가 완료된 
add() Stack frame Calculator Instance 
Operand Stack 
Local Variable 
3 
2 
}
int add(int i, int j) { 
i = 5; 
j = 3; 
return i + j; 
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
3 2 2 
3 
1 calculator 
0 args 
초기화가 완료된 
add() Stack frame Calculator Instance 
Operand Stack 
Local Variable 
1 3 
0 calculator 
2 
2 
}
int add(int i, int j) { 
i = 5; 
j = 3; 
return i + j; 
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
3 2 3 
3 
1 calculator 
0 args 
초기화가 완료된 
add() Stack frame Calculator Instance 
Operand Stack 
Local Variable 
1 5 
0 calculator 
2 
2 
}
Call by value 
자바의 기본 자료형(primitive type)은 call by value에 의해서 동작한다. 
즉, 메소드를 호출할 때 전달되는 인자의 값이 복사된다.
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
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 1 
public static void main(String[] args) { 
Student student = new Student("주한"); 
MessageRenderer mr = new MessageRenderer(); 
mr.callByReference(student); 
System.out.println("Name : " + student.name); 
}
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 1 
public 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 = "예은"; 
} 
0 student
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “예은” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 1 
public 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 = "예은"; 
} 
0 student
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “예은” 
Student Instance 
Case 1 
public static void main(String[] args) { 
Student student = new Student("주한"); 
MessageRenderer mr = new MessageRenderer(); 
mr.callByReference(student); 
System.out.println("Name : " + student.name); 
}
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
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 2 
public static void main(String[] args) { 
Student student = new Student("주한"); 
MessageRenderer mr = new MessageRenderer(); 
mr.callByReference(student); 
System.out.println("Name : " + student.name); 
}
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 1 
public 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(“예은”); 
} 
0 student
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
callByReference() 
Stack frame 
Operand Stack 
Local Variable 
Case 1 
public 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(“예은”); 
} 
0 student 
name = “예은” 
Student Instance
JVM Stacks Method 
Area 
JVM Heap 
main() Stack frame 
Operand Stack 
Local Variable 
1 student 
0 args 
name = “주한” 
Student Instance 
Case 1 
public static void main(String[] args) { 
Student student = new Student("주한"); 
MessageRenderer mr = new MessageRenderer(); 
mr.callByReference(student); 
System.out.println("Name : " + student.name); 
}
Call by reference 
자바의 모든 객체(인스턴스)는 call by reference에 의해서 동작한다. 
즉, 메소드를 호출할 때 전달되는 인자는 값이 아니라 참조하고 있는 주소 값이 전달된다.
참고 문서

Más contenido relacionado

La actualidad más candente

Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introductionJonathan Holloway
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action Alex Movila
 
4장. Class Loader
4장. Class Loader4장. Class Loader
4장. Class Loader김 한도
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework tola99
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first stepsRenato Primavera
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework Serhat Can
 
Spring 2.0 技術手冊第一章 - 認識 Spring
Spring 2.0 技術手冊第一章 - 認識 SpringSpring 2.0 技術手冊第一章 - 認識 Spring
Spring 2.0 技術手冊第一章 - 認識 SpringJustin Lin
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - CoreDzmitry Naskou
 
Maven Basics - Explained
Maven Basics - ExplainedMaven Basics - Explained
Maven Basics - ExplainedSmita Prasad
 
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...Edureka!
 
1장 Java란 무엇인가.key
1장 Java란 무엇인가.key1장 Java란 무엇인가.key
1장 Java란 무엇인가.key김 한도
 
En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023Jean-Michel Doudoux
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New FeaturesHaim Michael
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework IntroductionAnuj Singh Rajput
 

La actualidad más candente (20)

Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 
4장. Class Loader
4장. Class Loader4장. Class Loader
4장. Class Loader
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework
 
Spring boot
Spring bootSpring boot
Spring boot
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
Spring 2.0 技術手冊第一章 - 認識 Spring
Spring 2.0 技術手冊第一章 - 認識 SpringSpring 2.0 技術手冊第一章 - 認識 Spring
Spring 2.0 技術手冊第一章 - 認識 Spring
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Maven Basics - Explained
Maven Basics - ExplainedMaven Basics - Explained
Maven Basics - Explained
 
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
 
CORE JAVA
CORE JAVACORE JAVA
CORE JAVA
 
1장 Java란 무엇인가.key
1장 Java란 무엇인가.key1장 Java란 무엇인가.key
1장 Java란 무엇인가.key
 
Apache maven 2 overview
Apache maven 2 overviewApache maven 2 overview
Apache maven 2 overview
 
En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023En route vers Java 21 - Javaday Paris 2023
En route vers Java 21 - Javaday Paris 2023
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework Introduction
 

Similar a Java Virtual Machine, Call stack, Java Byte Code

Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicknight1128
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2도현 김
 
20130408 javap
20130408 javap20130408 javap
20130408 javapSukjin Yun
 
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8Sangmin Lee
 
Java 강의자료 ed11
Java 강의자료 ed11Java 강의자료 ed11
Java 강의자료 ed11hungrok
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계Chiwon Song
 
Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Sangon Lee
 
7가지 동시성 모델 람다아키텍처
7가지 동시성 모델  람다아키텍처7가지 동시성 모델  람다아키텍처
7가지 동시성 모델 람다아키텍처Sunggon Song
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 releaseJaehyeuk Oh
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍NAVER D2
 
Python on Android
Python on AndroidPython on Android
Python on Android용 최
 

Similar a Java Virtual Machine, Call stack, Java Byte Code (20)

Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamic
 
Java_01 기초
Java_01 기초Java_01 기초
Java_01 기초
 
Java 기초
Java 기초Java 기초
Java 기초
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
 
20130408 javap
20130408 javap20130408 javap
20130408 javap
 
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8
 
Java 강의자료 ed11
Java 강의자료 ed11Java 강의자료 ed11
Java 강의자료 ed11
 
Scala for play
Scala for playScala for play
Scala for play
 
Jvm
JvmJvm
Jvm
 
Java memory
Java memoryJava memory
Java memory
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계
 
Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Android ndk jni 설치및 연동
Android ndk jni 설치및 연동
 
7가지 동시성 모델 람다아키텍처
7가지 동시성 모델  람다아키텍처7가지 동시성 모델  람다아키텍처
7가지 동시성 모델 람다아키텍처
 
java_1장.pptx
java_1장.pptxjava_1장.pptx
java_1장.pptx
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 release
 
java_1장
java_1장java_1장
java_1장
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Jdk 7 3-nio2
Jdk 7 3-nio2Jdk 7 3-nio2
Jdk 7 3-nio2
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍
 
Python on Android
Python on AndroidPython on Android
Python on Android
 

Más de Javajigi Jaesung

나는 왜 TDD에 집착하는가?
나는 왜 TDD에 집착하는가?나는 왜 TDD에 집착하는가?
나는 왜 TDD에 집착하는가?Javajigi Jaesung
 
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵Javajigi Jaesung
 
패캠 네트워킹 데이 - 침묵으로 가르치기
패캠 네트워킹 데이 - 침묵으로 가르치기패캠 네트워킹 데이 - 침묵으로 가르치기
패캠 네트워킹 데이 - 침묵으로 가르치기Javajigi Jaesung
 
어느 40대 아저씨 이야기
어느 40대 아저씨 이야기어느 40대 아저씨 이야기
어느 40대 아저씨 이야기Javajigi Jaesung
 
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담Javajigi Jaesung
 
커뮤니티 활동과 스터디
커뮤니티 활동과 스터디커뮤니티 활동과 스터디
커뮤니티 활동과 스터디Javajigi Jaesung
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Javajigi Jaesung
 
2014년에 만든 나만의 이력서
2014년에 만든 나만의 이력서2014년에 만든 나만의 이력서
2014년에 만든 나만의 이력서Javajigi Jaesung
 
어떻게 배움을 만들어 갈 것인가
어떻게 배움을 만들어 갈 것인가어떻게 배움을 만들어 갈 것인가
어떻게 배움을 만들어 갈 것인가Javajigi Jaesung
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정Javajigi Jaesung
 

Más de Javajigi Jaesung (12)

나는 왜 TDD에 집착하는가?
나는 왜 TDD에 집착하는가?나는 왜 TDD에 집착하는가?
나는 왜 TDD에 집착하는가?
 
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
소프트웨어 학습 및 자바 웹 개발자 학습 로드맵
 
패캠 네트워킹 데이 - 침묵으로 가르치기
패캠 네트워킹 데이 - 침묵으로 가르치기패캠 네트워킹 데이 - 침묵으로 가르치기
패캠 네트워킹 데이 - 침묵으로 가르치기
 
어느 40대 아저씨 이야기
어느 40대 아저씨 이야기어느 40대 아저씨 이야기
어느 40대 아저씨 이야기
 
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
 
커뮤니티 활동과 스터디
커뮤니티 활동과 스터디커뮤니티 활동과 스터디
커뮤니티 활동과 스터디
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
2014년에 만든 나만의 이력서
2014년에 만든 나만의 이력서2014년에 만든 나만의 이력서
2014년에 만든 나만의 이력서
 
HTTP web server 구현
HTTP web server 구현HTTP web server 구현
HTTP web server 구현
 
어떻게 배움을 만들어 갈 것인가
어떻게 배움을 만들어 갈 것인가어떻게 배움을 만들어 갈 것인가
어떻게 배움을 만들어 갈 것인가
 
나, 우리, 스터디
나, 우리, 스터디나, 우리, 스터디
나, 우리, 스터디
 
ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정ORM을 활용할 경우의 설계, 개발 과정
ORM을 활용할 경우의 설계, 개발 과정
 

Java Virtual Machine, Call stack, Java Byte Code

  • 1. JVM 및 Call Stack
  • 2. 학습 목표 Java Virtual Machine의 메모리 관리 자바 바이트 코드 읽기
  • 4. Java Virtual Machine Class Loader System Operating System Java Threads Execution Engine Run-time Data Area Garbage Collector Java Application Java API Native Method Libraries
  • 5. ByteCode Link Verify Prepare Class Load Class Loader Resolve Initialize ByteCode Class File Memory
  • 6. Java API Execution Class Loader Engine Java Class System Runtime Data Areas PC Registers JVM Stacks Files Native Method Libraries Method Area Heap Native Method Stacks JVM은 Class Loader를 활용해 컴파일한 Byte Code를 Runtime Data Areas의 Method Area에 실행 가능한 상태로 Load한다.
  • 7. Execution Engine Class Loader System Operating System Java Threads Execution Engine Run-time Data Area Garbage Collector Java Application Java API Native Method Libraries
  • 8. Java API Execution Class Loader Engine Java Class System Runtime Data Areas PC Registers JVM Stacks Files Native Method Libraries Method Area Heap Native Method Stacks JVM의 Execution Engine은 Method Area에 Load되어 있는 Byte Code 정보를 활용해 자바 프로그램을 실행한다. Execution Engine은 ByteCode를 한 라인씩 실행(interpreting 방식)한다.
  • 9. Method Area 모든 Thread 들이 공유하는 메모리 영역이다. 자바 프로그램을 실행하기 위한 Class(Type), Method, Field 정보를 가진다. 프로그램에서 공유할 필요가 있는 정보를 가진다.
  • 10. 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를 가진다.
  • 11. Java API Execution Class Loader Engine Java Class System Runtime Data Areas PC Registers JVM Stacks Files Native Method Libraries Method Area Heap Native Method Stacks Method Area의 Byte Code 정보를 활용해 프로그램을 실행할 때는 JVM Stacks, Native Method Stacks 공간을 활용한다.
  • 12. JVM Stacks, Native Method Stacks 각 Thread마다 서로 다른 메모리가 할당된다. Thread가 시작할 때 생성된다. 각 Thread마다 서로 다른 메모리를 사용하기 때문에 여러 명의 사용자가 동시에 같은 method에 접근해도 문제가 발생하지 않는다.
  • 13. Java API Execution Class Loader Engine Java Class System Runtime Data Areas PC Registers JVM Stacks Files Native Method Libraries Method Area Heap Native Method Stacks JVM은 Heap에서 자바 프로그램을 실행할 때 자바 클래스의 인스턴스와 Array에 대한 메모리를 관리한다.
  • 14. 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)
  • 15. JVM Heap과 Method Area는 Thread가 메모리를 공유한다. Method Area constant pool JVM Heap Thread A (사용자 A) Thread B (사용자 B)
  • 16. Method Area는 클래스 ByteCode와 변하지 않는 값이 존재하기 때문에 이슈가 없다. Thread가 데이터를 공유함으로써 이슈가 있는 부분은 JVM Heap 메모리이다. Method Area constant pool JVM Heap Thread A (사용자 A) Thread B (사용자 B)
  • 17. Heap 모든 Thread 들이 공유하는 메모리 영역이다. JVM에서 대부분의 메모리 이슈가 집중되어 있는 부분이다. JVM에서 Memory가 할당, 해제(Garbage Collection)의 이슈는 대부분 Heap 메모리이다.
  • 18. 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); } }
  • 19. 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 Stacks main() Stack frame Operand Stack Local Variable 0 args 1. main method 실행을 위한 stack frame 생성
  • 20. 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 Stacks main() Stack frame Operand Stack Local Variable 0 args 1. main method 실행을 위한 stack frame 생성 2. Adder 생성자를 위한 stack frame 생성 Adder 생성자 Stack frame Operand Stack Local Variable 0 this
  • 21. 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 Stacks main() Stack frame Operand Stack Local Variable 0 args 1. main method 실행을 위한 stack frame 생성 2. Adder 생성자를 위한 stack frame 생성 3. 생성자 실행이 끝나면 Adder 생성자를 위한 stack frame 제거
  • 22. JVM Stacks main() Stack frame Operand Stack Local Variable 0 args 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); } 1. main method 실행을 위한 stack frame 생성 2. Adder 생성자를 위한 stack frame 생성 3. 생성자 실행이 끝나면 Adder 생성자를 위한 stack frame 제거 4. add method를 위한 stack frame 생성 } add method Stack frame Operand Stack Local Variable 2 2 1 5 0 this
  • 23. JVM Stacks main() Stack frame Operand Stack Local Variable 0 args 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); } 1. main method 실행을 위한 stack frame 생성 2. Adder 생성자를 위한 stack frame 생성 3. 생성자 실행이 끝나면 Adder 생성자를 위한 stack frame 제거 4. add method를 위한 stack frame 생성 5. add method에 대한 stack frame 제거 }
  • 24. JVM Stacks 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); } 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 제거 }
  • 26. Execution Engine 컴파일한 바이트 코드를 한 라인씩 읽어내려가면서 자바 프로그램을 실행한다.
  • 27. public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } javap –c HelloWorld.class } D:next-workspaceworkspacejavabin>javap -c HelloWorld.class Compiled 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 }
  • 28. D:next-workspaceworkspacejavabin>javap -verbose HelloWorld.class Classfile /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_SUPER Constant pool: javap –verbose HelloWorld.class #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
  • 29. { 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; }
  • 30. Bytecode Visualizer Eclipse 플러그인 활용 (http://www.slipp.net/questions/292)
  • 31. Java opcode(bytecode instruction) http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
  • 32. Prefix/ Suffix Operand Type i integer l long s short b byte c character f float d double z boolean a reference
  • 33. JVM Stacks add method Stack frame Operand Stack Local Variable 2 2 1 5 0 this load opcode Local Variable 영역의 값을 Operand Stack 영역으로 복사하는 명령어(instruction) JVM Stacks add method Stack frame Operand Stack Local Variable 2 2 1 5 0 this iload_1 실행 후 0 5
  • 34. JVM Stacks main method Stack frame Operand Stack Local Variable 1 adder 0 this store opcode Operand Stack 영역의 값을 Local Variable 영역으로 이동하는 명령어(instruction) istore_2 실행 후 0 7 JVM Stacks main method Stack frame Operand Stack Local Variable 2 7 1 adder 0 this
  • 35. invoke* opcode : 생성자, method를 호출할 때 사용하는 opcode • invokestatic : 클래스(static) method를 호출 • invokeinterface : interface method를 호출 • invokespecial : 생성자 또는 인스턴스 method(다형성 X) 호출 • Invokevirtual : 인스턴스 method를 호출(다형성 O)
  • 36. Case 1 public class StringConcatenations { public String concat1(String start, String end) { return start + end; } public void concat2(StringBuffer start, String end) { start.append(end); } }
  • 37. Case 2 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"); } }
  • 39. Case 3 public class MyFor { public int sum(int[] values) { int sum = 0; for (int i = 0; i < values.length; i++) { sum +=- values[i]; } return sum; } }
  • 41. 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); } }
  • 42. D:next-workspaceworkspacejavabin>javap -c net/slipp/Adder Compiled 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 }
  • 43. D:next-workspaceworkspacejavabin>javap -c Adder.class Compiled 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)로 구성된다.
  • 44. JVM Stacks Method Area JVM Heap JVM은 Method Area에 저장되어 있는 Bytecode를 interpreting 방식으로 읽어 실행해 나간다. 먼저 Adder의 main()가 Entry Point가 된다. main() Stack frame Operand Stack Local Variable 0 args
  • 45. public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Method Area에 있는 Adder 정보를 활용해 Heap 메모리에 Adder Instance를 생성한 후 Operand Stack 0에 Adder Instance에 대한 reference를 저장 Adder Instance 0 adder Method Area
  • 46. public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup JVM Stacks JVM Heap main() Stack frame Operand Stack 1 adder Local Variable 0 args Operand Stack 0에 Adder Instance에 대한 reference를 Operand Stack 1에 복사한다. Adder Instance 0 adder Method Area
  • 47. public static void main(java.lang.String[]); Code: 3: dup 4: invokespecial #21 // Method "<init>":()V JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Adder 클래스의 기본 생성자(Object 기본 생성자)를 호출한다. Adder 기본 생성자 Stack Frame이 생성된다. Adder Instance 0 adder Adder 생성자 Stack frame Operand Stack Local Variable 0 this Method Area
  • 48. public net.slipp.Adder(); Code: 0: aload_0 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Adder 생성자 Stack Frame의 Local Variable의 index 0의 값을 Operand Stack으로 로드한다. Adder Instance 0 adder Adder 생성자 Stack frame Operand Stack 0 this Local Variable 0 this Method Area
  • 49. public net.slipp.Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Adder Instance에 대한 실질적인 초기화가 이 단계에서 진행된다. 초기화가 완료된 Adder Instance 0 adder Adder 생성자 Stack frame Operand Stack Local Variable 0 this Method Area
  • 50. public net.slipp.Adder(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Adder 기본 생성자에 대한 Stack Frame이 JVM Stack에서 제거된다. 0 adder 초기화가 완료된 Adder Instance Method Area
  • 51. public static void main(java.lang.String[]); Code: […] 4: invokespecial #21 // Method "<init>":()V 7: astore_1 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Operand Stack에서 pop한 결과를 Local Variable의 index 1번에 저장한다. 1 adder 초기화가 완료된 Adder Instance Method Area
  • 52. public static void main(java.lang.String[]); Code: […] 7: astore_1 8: aload_1 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Variable의 index 1번에 저장된 값을 Operand Stack에 push한다. 1 adder 초기화가 완료된 Adder Instance 0 adder Method Area
  • 53. public static void main(java.lang.String[]); Code: […] 8: aload_1 9: iconst_5 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Method Area의 constant pool에 존재하는 상수 값 5를 Operand Stack에 push한다. 1 adder 초기화가 완료된 Adder Instance 0 adder Method Area constant pool 1 2 … 1 5 5
  • 54. public static void main(java.lang.String[]); Code: […] 9: iconst_5 10: iconst_2 JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 0 args Method Area의 constant pool에 존재하는 상수 값 2를 Operand Stack에 push한다. 1 adder 초기화가 완료된 Adder Instance 0 adder constant pool 1 2 … 1 5 5 2 2
  • 55. public static void main(java.lang.String[]); Code: […] 10: iconst_2 11: invokevirtual #22 // Method add:(II)I JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args add() 메소드에 대한 Stack frame을 JVM Stack에 push하고 main() 메소드의 operand stack의 값을 add() 메소드에 복사한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 add() Stack frame Operand Stack Local Variable 2 2 1 5 0 adder Method Area
  • 56. int add(int, int); Code: 0: iload_1 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args add() 메소드 Stack Frame의 Local Variable의 index 1번 값을 Operand Stack에 push한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 add() Stack frame Operand Stack 0 5 Local Variable 2 2 1 5 0 adder Method Area
  • 57. int add(int, int); Code: 0: iload_1 1: iload_2 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args add() 메소드 Stack Frame의 Local Variable의 index 2번 값을 Operand Stack에 push한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 add() Stack frame Operand Stack 1 2 0 5 Local Variable 2 2 1 5 0 adder Method Area
  • 58. int add(int, int); Code: 0: iload_1 1: iload_2 2: iadd JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Operand Stack의 인자를 iadd에 전달해 덧셈을 실행한다. 실행한 결과를 Operand Stack에 저장한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 add() Stack frame Operand Stack 0 7 Local Variable 2 2 1 5 0 adder Method Area
  • 59. int add(int, int); Code: […] 2: iadd 3: ireturn JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args add() Stack Frame의 operand stack 값을 main() 메소드로 복사하고 add() Stack Frame을 pop한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 0 7 Method Area
  • 60. public static void main(java.lang.String[]); Code: […] 11: invokevirtual #22 // Method add:(II)I 14: istore_2 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args Operand Stack 값을 pop해서 Local Variable의 index 2번에 저장한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 2 7 Method Area
  • 61. public static void main(java.lang.String[]); Code: […] 14: istore_2 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args PrintStream에 대한 reference를 얻어 operand stack index 0에 저장한다. 1 adder 초기화가 완료된 Adder Instance constant pool 1 2 … 5 2 7 PrintStream Instance 0 out Method Area class variables
  • 62. public static void main(java.lang.String[]); Code: […] 15: getstatic #24 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_2 JVM Stacks JVM Heap main() Stack frame Operand Stack 1 7 0 out Local Variable 0 args Local Variable index 2 값을 operand stack에 push 한다. 1 adder 초기화가 완료된 Adder Instance class variables constant pool 1 2 … 5 2 7 Method Area PrintStream Instance
  • 63. public static void main(java.lang.String[]); Code: […] 18: iload_2 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 0 args PrintStream 인스턴스의 println() 메소드에 operand 값을 인자로 전달한다. 1 adder 초기화가 완료된 Adder Instance class variables constant pool 1 2 … 5 2 7 Method Area PrintStream Instance println() Stack frame Operand Stack Local Variable 1 7 0 this
  • 64. 애플리케이션을 종료한다. JVM Stacks JVM Heap class variables constant pool 1 2 … 5 public static void main(java.lang.String[]); Code: […] 19: invokevirtual #30 // Method java/io/PrintStream.println:(I)V 22: return 초기화가 완료된 Adder Instance 시간이 지나면 Garbage Collector에 의해 GC 대상이 된다. Method Area PrintStream Instance
  • 66. 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); } }
  • 67. D:next-workspaceworkspacejavabin>javap -c net/slipp/Adder Compiled 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 }
  • 68. public static void main(java.lang.String[]); Code: 0: new #1 // class net/slipp/Adder 3: dup JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack 1 adder Local Variable 0 args Adder Instance 0 adder
  • 69. public static void main(java.lang.String[]); Code: […] 4: iconst_5 5: iconst_2 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args Adder Instance 0 adder constant pool 1 2 … 1 5 5 2 2 Method Area
  • 70. public static void main(java.lang.String[]); Code: […] 4: iconst_5 5: iconst_2 6: invokespecial #26 // Method "<init>":(II)V JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args Adder Instance constant pool 1 2 … 5 Adder 생성자 Stack frame Operand Stack Local Variable 2 2 1 5 0 adder Method Area
  • 71. net.slipp.Adder(int, int); Code: […] 4: aload_0 5: iload_1 JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args Adder Instance constant pool 1 2 … 5 Adder 생성자 Stack frame Operand Stack 1 5 0 adder Local Variable 2 2 1 5 0 adder Method Area
  • 72. net.slipp.Adder(int, int); Code: […] 5: iload_1 6: putfield #14 // Field i:I JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args constant pool 1 2 … 5 Adder 생성자 Stack frame Operand Stack Local Variable 2 2 1 5 0 adder Adder Instance int i = 5 Method Area
  • 73. net.slipp.Adder(int, int); Code: […] 9: aload_0 10: iload_2 11: putfield #16 // Field j:I JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args constant pool 1 2 … 5 Adder 생성자 Stack frame Operand Stack Local Variable 2 2 1 5 0 adder Adder Instance int i = 5 int j = 2 Method Area
  • 74. public int add(); Code: 0: aload_0 1: getfield #14 // Field i:I 4: aload_0 5: getfield #16 // Field j:I JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args constant pool 1 2 … 5 add() Stack frame Operand Stack 2 2 1 5 Local Variable 0 adder 초기화가 완료된 Adder Instance int i = 5 int j = 2 0 adder Method Area
  • 77. JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args Adder Instance constant pool 1 2 … 5 add() Stack frame Operand Stack 1 2 0 5 Local Variable 2 2 1 5 0 adder Method Area
  • 78. public class Adder { int add(int i, int j) { return i + j; } } JVM Stacks main() Stack frame Operand Stack Local Variable 1 adder 0 args add() Stack frame Operand Stack 1 2 0 5 Local Variable 2 2 1 5 0 adder 사용자 1 = Thread 1 JVM Stacks main() Stack frame Operand Stack Local Variable 1 adder 0 args add() Stack frame Operand Stack 1 2 0 5 Local Variable 2 2 1 5 0 adder 사용자 2 = Thread 2
  • 79. JVM Stacks JVM Heap main() Stack frame Operand Stack Local Variable 1 adder 0 args constant pool 1 2 … 5 Adder Instance int i = 5 int j = 2 Method Area
  • 80. JVM Heap Adder Instance int i = 5 int 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; } }
  • 81. Java API Execution Class Loader Engine Java Class System Runtime Data Areas PC Registers JVM Stacks Files Native Method Libraries Method Area Heap Native Method Stacks JVM의 Stacks 영역은 Thread 별로(사용자) 생성된다. 따라서 각 Stacks 영역 사이에는 영향을 미치지 않는다. 이를 Thread Safe하다고 한다. JVM의 Heap 영역은 모든 Thread가 공유한다. 따라서 Heap에 존재하는 Object의 상태 값은 Thread 사이에 영향을 받는다. 이를 Thread Safe하지 않다고 한다.
  • 82. 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에서 재사용할 수 있다.
  • 83. 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별로 독립적으로 실행하려면 매번 인스턴스를 생성해야 한다.
  • 84. Call by value와 Call by reference
  • 85. 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); } }
  • 86. public static void main(String[] args) { Calculator calculator = new Calculator(); int i = 3; int j = 2; calculator.add(i, j); JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 2 3 1 calculator 0 args 초기화가 완료된 add() Stack frame Calculator Instance Operand Stack Local Variable 3 2 }
  • 87. int add(int i, int j) { i = 5; j = 3; return i + j; JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 3 2 2 3 1 calculator 0 args 초기화가 완료된 add() Stack frame Calculator Instance Operand Stack Local Variable 1 3 0 calculator 2 2 }
  • 88. int add(int i, int j) { i = 5; j = 3; return i + j; JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 3 2 3 3 1 calculator 0 args 초기화가 완료된 add() Stack frame Calculator Instance Operand Stack Local Variable 1 5 0 calculator 2 2 }
  • 89. Call by value 자바의 기본 자료형(primitive type)은 call by value에 의해서 동작한다. 즉, 메소드를 호출할 때 전달되는 인자의 값이 복사된다.
  • 90. 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
  • 91. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 1 public static void main(String[] args) { Student student = new Student("주한"); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }
  • 92. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 1 public 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 = "예은"; } 0 student
  • 93. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “예은” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 1 public 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 = "예은"; } 0 student
  • 94. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “예은” Student Instance Case 1 public static void main(String[] args) { Student student = new Student("주한"); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }
  • 95. 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
  • 96. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 2 public static void main(String[] args) { Student student = new Student("주한"); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }
  • 97. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 1 public 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(“예은”); } 0 student
  • 98. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance callByReference() Stack frame Operand Stack Local Variable Case 1 public 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(“예은”); } 0 student name = “예은” Student Instance
  • 99. JVM Stacks Method Area JVM Heap main() Stack frame Operand Stack Local Variable 1 student 0 args name = “주한” Student Instance Case 1 public static void main(String[] args) { Student student = new Student("주한"); MessageRenderer mr = new MessageRenderer(); mr.callByReference(student); System.out.println("Name : " + student.name); }
  • 100. Call by reference 자바의 모든 객체(인스턴스)는 call by reference에 의해서 동작한다. 즉, 메소드를 호출할 때 전달되는 인자는 값이 아니라 참조하고 있는 주소 값이 전달된다.

Notas del editor

  1. 4
  2. 7
  3. 9
  4. 10
  5. 12
  6. 17
  7. 26
  8. 81