Hello.java(사람용) -> Hello.class(JVM용) -> 기계어
javac가 java파일을 class파일로 번역해주고 JVM이 2차번역해서 컴퓨터가 이해할 수 있게 기계어로 바꿔준다.
최종적으로 CPU가 실행함으로써 터미널에 결과가 출력된다
Hello.java->javac->JVM->기계어
hello.c -> 컴파일러 -> 기계어
왜 이렇게 자바는 복잡하게 만들어놓은거야?
c언어의 경우 os별로 다른 컴파일러가 있어서 윈도우,맥,리눅스에 뿌릴라면 3개의 컴파일러를 다돌려야됨.
근데 자바의 경우에는 javac로 컴파일 하고 난 뒤에 .class파일은 각 Os에 설치되어있는 JVM이 번역해줘서 Write Once Run Anywhere가 가능해진다
한 번 실행되면 어디서든 돌아갈 수 있다는거임
Write Once Run Anywhere = 면접에서도 자주 다루는 내용이니까 잘 기억해두기
바이너리코드, 기계어, 바이트코드 ,플랫폼
바이너리코드 : 0,1로 된 코드 전부
기계어 : 그 중 cpu가 바로 실행할 수 있는것
(그럼 모든 바이너리 코드를 cpu가 다 읽을 수 있는건 아니네)
바이트코드 : 바이너리 코드 중 JVM 같은 가상 머신이 해석하는 명령어 (CPU는 바로 읽지 못함)
플랫폼 : OS와 cpu의 조합 기계어는 플랫폼마다 다르다.
플랫폼에 독립적이다? 바이트코드(.class)가 어떤 플랫폼에 들어가든 JVM이 알아서 해줄거니까 자바는 플랫폼 독립적인거지
jdk = jre + 개발도구
jre = jvm + 라이브러리
jdk에 javac 컴파일러가 필요하니까 컴파일이 필요하면 개발도구모음이 필요하다
LTS버전은 Long Term Support로 오래 지원해주는 버전임
가령 LTS가 아닌 10 버전을 한다고 하면 , 라이선스 지원자체가 갑자기 끝날 수 있음. 안정성 개박살
LTS의 경우에는 어떤 버전에 어떤 특징이 있는지 한 번 보면 도움이 될 수 있다
먼저 Hello.class파일이 jvm안에서 읽어졌을때 제일먼저 Class Loader가 .class 파일을 읽어서 메모리에 올려준다
메모리에 올라간 후 Runtime Data Area (JVM이 OS에게 할당받아 쓰는 전용 메모리 공간) 이 공간 안에 Method Area/Heap/Thread(main)안에 Stack이 존재함
먼저 Method Area에 Hello 클래스의 정보가 들어온다. 간단하게 얘가 어떻게 생겨먹었는지
그럼 스택에 메인 프레임이 올라가고 힙에는 new로 만든 객체들이 올라가게된다.
main()프레임도 일단 가볍게 넘어가자.
Execution Engine에서는 메모리에 있는 바이트코드를 기계어로 바꿔주고 이걸 OS/CPU가 실행한다.(여기가 두번째 번역구간임! 한번더기계어로 변환하는 과정)
마지막으로 Garbage Collector가 정리해줌.안쓰는 메모리 자동수거
도서관에서 필요할 때 책을 빌려오듯, 실행 시 필요한 .class 파일을 읽어 메모리에 올린다 (Lazy Loading / 지연 로딩).
로딩 (Loading): 클래스 파일 찾아서 읽기
링킹 (Linking): 메모리 공간 확보
초기화 (Initialization): 공간에 실제 값 세팅
JVM이 OS로부터 할당받아 사용하는 전용 메모리 공간.
Method Area: 클래스의 기본 구조/정보가 저장되는 공간.
Heap: new 연산자로 생성된 객체들이 저장되는 공간.
Stack (Thread): 메서드 호출 시 프레임이 쌓이며, 지역 변수 등이 저장되는 공간.
인터프리터 방식 - 동시통역 - 한줄읽고 바꿔실행
장점 준비없이바로시작
단점 같은코드 100번실행 -> 100번 통역!
Jit 컴파일러- 자주쓰는 말은 번역문을 미리 적어두고 읽는다
자주 실행되는 코드(핫스팟)을 통째로 기계어로 바꿔 캐시에 저장해두고 재사용
장점 반복 실행이빠르다
단점 컴파일하는데 시간이 든다 (워밍업)
더 이상 참조되지 않는 메모리(Heap 영역)를 자동으로 수거하고 정돈한다.
cf)
마크(java edition)하다가 화면 멈출때?
원인은 바로 GC 동작에 의한 Stop-The-World (STW) 현상!
오랫동안 남은 객체들이 쌓여 있는 Old Generation 영역을 청소(Major/Full GC)할 때, JVM은 메모리 정리의 안전성을 위해 GC 전용 쓰레드를 제외한 모든 애플리케이션 작업(게임을 포함한 모든 쓰레드)을 일시 정지시킨다.