JVM, JDK, JRE

김민지·2022년 10월 19일
0

자바

목록 보기
7/21
post-thumbnail
post-custom-banner

JVM

  • jvm은 자바파일을 실행하기 위한 가상의 컴퓨터다
    자바파일만으로는 cpu가 인식하지 못하므로 기계어로 컴파일하는 과정을 거쳐야 실행할수있다
    그 일을 해주는것이 jvm이다 jvm은 java파일을 기계어로 바로 변환하진 않는다
    왜냐하면 바로 기계어로 변환하려면 os에 종속적이될수밖에 없기때문이다.
    os마다 기계어의 문법(?)이 다르기 때문에 같은 기계어여도 다르게 해석된다.
    os에 종속적이지 않기 위해 jvm은 jvm이 인식할 수 있는 자바 바이트코드(.class파일)로 변환한다
    그리고 os에게 해석을 해준다. 그러면 os에 종속적이지 않게된다.

바이트코드

  • 가상 컴퓨터(VM)에서 돌아가는 실행 프로그램을 위한 이진 표현법.
    바이트 코드(Java bytecode)는 JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미한다.

자바 프로그램의 실행단계

자바 컴파일러에 의해 .java -> .class 로 변환된다
jvm은 .class를읽어서 어느 운영체제든 간에 자바를 실행할 수 있게 만들어준다

JVM의 수행과정

1) 클래스 로더 : 클래스 파일을 메모리에 JVM내에 로드하고 링크를 통해 배치한다.
2) 실행 엔진 : 클래스 로더를 통해 JVM의 Runtime Data Area에 배치된 바이트 코드들을 명령어 단위로 읽어서 실행
3) GC : 힙메모리 영역에 생성된 객체들 주엥서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 한다
4) Runtime Data Area : JVM의 메모리영역, 자바 애플리케이션을 실행할때 사용되는 데이터들을 적재하는 영역이다

실행엔진

  • 인터프리터: 바이트 코드를 한줄 씩 실행. 그리고 반복되는 코드가 있다면 JIT컴파일러로 보낸다
  • JIT 컴파일러: 자바->네이티브코드로 컴파일하는 애
  • JIT 컴파일러: 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면
    JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다. 그 다음부터
    인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다

Runtime Data Area

1) 메서드 영역 : 모든 스레드가 공유, 바이트 코드 보관
2) 힙영역 : 모든 스레드가 공유, new로 생성된 객체, 배열이 생성됨
3) 스택 영역: 메서드 호출마다 그 메서드만의 공간을 생성, 그 메서드안에서 사용되는 값들을 저장
4) pc레지스터: 쓰레드 마다 쓰레드 내 현재 실행할 스택 프레임을
가리키는 포인터가 생성된다.
5) native method stack: 자바외 언어로 작성된 코드를 위한 메모리 영역

  • native라는 키워드가 붙으면 자바로 구현한 코드가 아니라는 얘기다
  • 힙, 메서드 영역은 모든 스레드에서 공용으로 사용하는 영역이고
    나머지 스택, PC, 네이티브 메서드 스택은 스레드마다 주어지는 공간이다

JNI

  • Java Native Interface
    자바 코드의 장점은 플랫폼으로부터 독립적이라는 것입니다. 쉽게 말해, 자바로 코딩한 소프트웨어는 리눅스에서도 동작하고, 윈도우에서도 동작합니다. 왜냐하면 두 OS 모두 JVM(Java Virtual Machine)을 사용할 수 있기 때문입니다. JVM은 플랫폼에 상관없이 자바 코드를 읽고 실행합니다. 구체적으로 말하면 자바 언어로 코딩해 만든 .java 파일을 컴파일한 .class 파일을 읽습니다.
    그러나 자바로 개발한 소프트웨어일지라도 네이티브 코드(native code) 사용이 필요한 순간이 있습니다.
    네이티브 코드란 C, C++처럼 (JVM 같은)인터프리터 없이 운영체제가 읽을 수 있는 형태로 컴파일해 사용 가능한 코드를 말합니다.
    네이티브 코드가 사용되는 경우는 언제일까요? 예를 들면, 하드웨어 자체 기능을 동작시켜야 하는 경우, 프로세스의 성능을 향상해야 하는 경우, 이미 네이티브 코드로 작성된 라이브러리를 사용하고 싶은 경우 등이 있을 수 있습니다.
    이런 필요를 충족시키기 위해 JVM은 자바 코드와 네이티브 코드를 연결할 수 있는 인터페이스를 제공하고 있습니다. 그게 바로 JNI입니다.

  • 다른 언어들로 작성된 라이브러리들을 호출하거나 반대로 호출되는 것을 가능하게 하는 프로그래밍 프레임워크

  • Java로 다시 작성하는 대신 기존 라이브러리를 재사용하고 싶다

  • 네이티브 메서드들은 항상 JNI를 통해서 사용해야한다

  • 자바로 쓰인 코드는 바이트코드로 빌드되어, jvm 이 이해할 수 있는 명령어로 실행이 됩니다
    런타임에는 클래스로더에서 이를 메모리에 올려서 실행하게 되죠
    근데 네이티브 코드로 짜여지고 빌드된 공유 라이브러리는 바이트코드로 빌드되는게 아니고 jvm 위에서 동작하는 방식도 아니죠
    다만 java 와 네이티브 코드 상호간에 호출할 수 있는 인터페이스 = JNI를 통해 콜을 떄리는겁니다

클래스 로더

1) 로딩

  • Bootstrap, Extension, Application - 이 컴포넌트들에 의해 클래스들이 로드된다. 클래스 로더들이면서 이 세가지 클래스로더에 의해 클래스가 로드됩니다.
    부트스트랩 클래스로더 : 기본 자바 API라이브러리 로드
    확장 클래스로더 : 확장코어 클래스파일 로드
    애플리케이션 클래스로더 : 애플리케이션 레벨에 있는 클래스들을 로드
    2) 연결
    검증 (verify) - 바이트코드 검증기는 생성된 자바 바이트코드가 적절한지 아닌지에 대해서 검증하며 검증이 실패할 경우 검증오류를 내보내게 됩니다.
    준비 (prepare) - 모든 정적변수의 메모리가 할당되며 기본 default 값으로 할당됩니다.(아직 초기화되지는 않음)
    해석 (resolve) - 모든 심볼릭한(명확하게 정의되지 않은) 메모리 참조를 메소드 영역에 있는 타입으로 직접 참조합니다.
  1. 초기화(initialize)
    클래스 로딩의 마지막 단계로써 모든 정적 변수가 자바 코드에 명시된 값으로 초기화되며 정적블록이 실행됩니다.

동적로딩 정적로딩

동적 로딩

  • 프로그램을 실행할 때, 필요할 때마다 동적으로 메모리를 생성하고, 필요없는 메모리는 자동으로 메모리에서 소멸시킨다.
  • 필요한 기능만 메모리에 불러와 사용하기 때문에, 큰 프로그램도 작은 메모리에서 실행이 가능하다.
  • 프로그램의 실행 속도가 느려질 수 있다.

정적 로딩

  • 프로그램을 실행할 때, 모든 실행파일이 메모리에 로드된다.
  • 모든 기능이 메모리에 존재하므로, CPU가 필요로하는 기능을 빠르게 메모리에서 가져와 사용할 수 있다.
  • 메모리를 많이 차지한다.

출처
https://doozi0316.tistory.com/entry/1%EC%A3%BC%EC%B0%A8-JVM%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EA%B2%83%EC%9D%B8%EA%B0%80
https://blog.wanzargen.me/16
https://steady-coding.tistory.com/305
https://mommoo.tistory.com/71
https://change-words.tistory.com/247
https://sas-study.tistory.com/262

profile
안녕하세요!
post-custom-banner

0개의 댓글