```
package studyGroup;
public class Study1 {
public static void main(String[] args) {
System.out.println("Hello OOP");
}
}
```
⇒ 이 간단한 코드를 실행 할 때, 컴퓨터 상에서 일어나는 과정을 모두 설명 할 수 있는가??
- 일어나는 과정
1. JRE는 일단 main 메소드를 찾는다. 없다면 에러를 발생 시킬 것이다.
2. main 메소드를 찾았다면, JRE는 JVM를 가동 시킨다. 가상의 기계인 JVM에 전원을 넣어 부팅하는 것.
⇒ virtual machine인 jvm에 무슨 전원을 넣는단 말인가?? 찾아보고 공부 해보세요. 컴퓨터 영역에서 physical 영역과 virtual 영역의 차이를 아는 것이 중요합니다. 이 개념은 네트워크에서도 통용됩니다.
3. 부팅된 JVM은 목적파일( 바이트 코드 파일, .class 파일)을 받아 실행한다. 실행하기 전에 JVM은 반드시 포함되어야 하는 패키지 java.lang 패키지를 java 메모리 영역 static 영역에 가져다 놓는다.
⇒ 덕분에 System.out.println( )과 같은 메소드를 사용 할 수 있게 된다.
- 실제 바이트코드 모습
```java
// class version 61.0 (61)
// access flags 0x21
public class project2/Study1 {
// compiled from: Study1.java
// access flags 0x1
public <init>()V
L0
LINENUMBER 5 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lproject2/Study1; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "Hello OOP"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 11 L1
NEW studyGroup/Hello
DUP
INVOKESPECIAL studyGroup/Hello.<init> ()V
ASTORE 1
L2
LINENUMBER 13 L2
RETURN
L3
LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
LOCALVARIABLE hello LstudyGroup/Hello; L2 L3 1
MAXSTACK = 2
MAXLOCALS = 2
}
```
1. JVM은 개발자가 작성한 모든 클래스와 임포트 패키지 역시 스태틱 영역에 가져다 놓습니다.
⇒ 여기선 Study1이라는 클래스가 스태틱 영역에 올라가겠죠. 그리고 스태틱 영역의 Study1은 내부에 main 메소드를 포함 합니다.
2. 이제 System.out.println() 이전에 main( ) 메서드가 실행 되기 위해 스택 메모리 영역에 main( ) 메서드가 할당 됩니다.
3. 그리고 main(String[] args) 메서드 안에 args라는 매개 변수가 main 스택 프레임 안에 지역 변수로 할당 됩니다.
4. 마지막으로 main 메서드 스택 프레임 안에 작성한 System.out.println( ) 메서드가 실행이 됩니다.
⇒ System.out.println( )은 콘솔 화면에 데이터를 찍어주는 작업이기에, 입출력 장치의 도움이 필요합니다. 입출력 장치의 도움은 운영체제(윈도우)에게 시스템 콜로 부탁해서 커널 영역에서 이루어져야 하는 작업입니다.
5. main( ) 메서드가 끝나면 JRE는 JVM을 종료하고, JRE도 운영체제 상의 메모리에서 사라집니다.
```java
public class Study1 {
public static void main(String[] args) { => { 열린 중괄호 = 스택의 시작
System.out.println("Hello OOP");
} => 닫힌 중괄호 : 스택의 종료, 끝
} -> class의 중괄호는 해당사항 X
```