본문 바로가기

D.S/DE

220403일 -JAVA 동작 #1

728x90

 

DevOps 쪽이 Java로 많이 이루어져있다보니 자바 동작원리나 언어를 다시 좀 봐야겠다는 생각이 들었다.

 


 

JVM

  • OS에 종속받지 않고 CPU가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터
  • java 소스코드는 JVM을 통해 어떤 OS든 상관없이 실행할 수 있도록 해줌.
    • java 소스코드(.java) → (JVM이 이해할 수 있는) 자바 바이트코드로 변환(.class) → 이진코드(기계어)로 컴파일
    • java코드 → (자바 컴파일러=javac.exe) → .class → (JIT) → 기계어
  • JIT (just-in-time compiler)
    • 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일러
    • 인터프리터 방식 단점을 보완하기 위해 도입. 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경 → 기계어로 직접 실행
    • 기계어로 컴파일된 코드는 캐시에 보관된다 → 자주 실행되는 코드들은 JIT 컴파일, 한번 실행되는 코드들은 인터프리팅

javac.exe : .class 파일 생성 (자바 바이트 코드)

java.exe : JVM을 구동시키기 위한 프로그램. .class 파일을 실행시킬 수 있음

 

이미지 출처: https://doozi0316.tistory.com/entry/1주차-JVM은-무엇이며-자바-코드는-어떻게-실행하는-것인가

 

 

Run time data area

프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간

이미지 출처: https://d2.naver.com/helloworld/1230

 

Thread → PC register

  • thread에 생성되는 공간. 쓰레드가 어떤 부분을 어떤 명령으로 실행햐할 지에 대한 기록 저장

 

Thread → JVM stack

  • 변수나 임시데이터(지역변수 등등), 스레드나 메소드의 정보 저장
  • 메소드 호출시 필요한 데이터 저장

 

Thread → Native method stack

  • java가 아닌 다른 언어(C++ 등) 코드를 java native interface를 통해 호출하여 수행하기 위한 스택

 

Method area

  • 모든 스레드가 공유하는 영역으로 JVM이 시작될 때 생성
  • JVM이 읽어 들인 정보( 각각의 클래스와 인터페이스에 대한 런타임 상수 풀, 필드와 메서드 정보, static 변수, 메서드의 바이트코드 등)를 보관.
  • JVM 벤더마다 다양한 형태로 구현 가능
  • 오라클 핫스팟 JVM(HotSpot JVM)에서는 흔히 Permanent Area, 혹은 Permanent Generation(PermGen)이라고 불린다.
  • 메서드 영역에 대한 가비지 컬렉션은 JVM 벤더의 선택 사항

 

Runtime constant pool

  • 클래스 파일 포맷에서 constant_pol 테이블에 해당하는 영역
  • 메서드 영역에 포함되는 영역이긴 하지만 JVM 동작에서 가장 핵심적인 역할을 수행하는 곳이라 따로 명시
  • 각 클래스와 인터페이스의 상수뿐만 아니라 메서드와 필드에 대한 모든 레퍼런스까지 담고 있는 테이블
  • 어떤 메서드나 필드를 참조할 때 JVM은 런타임 상수 풀을 통해 해당 메서드나 필드의 실제 메모리상 주소를 찾아서 참조

 

Heap

  • 인스턴스 또는 객체를 저장하는 공간으로 가비지 컬렉션 대상. JVM 성능 등의 이슈에서 가장 많이 언급되는 공간.
  • 힙 구성 방식이나 가비지 컬렉션 방법 등의 JVM 벤더의 재량

이미지 출처: https://doozi0316.tistory.com/entry/1주차-JVM은-무엇이며-자바-코드는-어떻게-실행하는-것인가

 

  • 객체를 저장하는 가상메모리 공간. new 연산자로 생성되는 개체와 배열을 저장
  • 세 부분으로 나눠져 있음
  • New/young, old 영역은 가비지 콜렉터에 의해 관리된다.
  • 처음 생성된 객체는 Eden에 위치 → MinorGC에 의해 사용안되는 객체 제거→ 살아남은 객체는 survivor1,2을 왔다갔다 이동하게 됨 → 반복되는minorGC에 오래 살아남은 객체들은 Old gen으로 이동. (young gen 영역이 가득 찼을 경우에도 이동)

 

GC(가비지 콜렉터)

힙 영역에서 발생

  • 역할
    • 메모리 할당
    • 사용중인 메모리 인식
    • 사용하지 않는 메모리 인식
  • GC방식
    • 시리얼 콜렉터
    • 병력 콜렉터
    • 병렬 콤팩팅 콜렉터
    • CMS 콜렉터
    • G1 콜렉터
  • 종류
    • 마이너 GC: young 영역에서 발생
    • 메이저 GC(full GC): old, perm 영역에서 발생
    • Mark-sweap-compact:
    • sweap 과정에서 발생한 scattered holes를 메우기?위해 재구성 과정(compact) 과정을 거침
    • compact 과정에서 GC를 수행하는 스레드를 제외한 나머지 스레드가 정지
    • full GC가 자주 일어나고 수행시간이 길 경우 WAS 응답시간에 영향
  • 두 가지 GC가 어떻게 상호작용 하느냐에 따라 GC 방식에 차이가 나고 성능에 영향을 준다.
  • GC가 발생하거나 객체가 각 영역에서 다른 영역으로 이동할 떄 애플리케이션의 병목이 발생하면서 성능에 영향을 주게 된다.
  • 핫스팟 JVM에서는 스레드 로컬 할당 버퍼(TLABs)를 사용. 이를 통해 각 스레드별 메모리 버퍼를 사용하면 다른 스레드에 영향을 주지 않는 메모리 할당 작업이 가능
  • Full GC를 수행하는 시점에는 응답시간이 느려진다. (→ 카프카 등에서 이로 인해 응답시간이 느려져 주키퍼와의 통신이 끊어질 수 있으니 응답대기초를 얼만큼 해라 그런 조언이 있었다.) 강제로 gc하는 코드를 넣었을 때 응답속도가 매우 느려지는 테스트를 많이 볼 수 있음.
  • GC튜닝을 통해 FULL GC의 횟수 또는 수행 시간 조절 가능
    • young 영역 크기 조절: old 영역으로 넘어가는 객체 수를 줄이면 Full GC 빈도 줄일 수 있음
    • old 영역 크기 조절:
    • 크기 줄이면 Full GC 수행시간 줄어듦, but 수행 자주 일어나거나 OOM 일어날 수 있음
    • 크기 늘리면 Full GC 발생빈도 줄일 수 있지만 수행시간 늘어남

 

JDK(java development kit)

  • java를 사용하기 위해 필요한 모든 기능을 갖춘 java용 SDK
  • JRE 포함
  • 프로그램을 생성, 실행, 컴파일할 수 있음

 

JRE(java runtime environment)

  • JVM+자바 클래스 라이브러리 등으로 구성
  • 컴파일된 JAVA 프로그램을 실행하는데 필요한 패키지

 

참조

 

언어 얘기가 나왔는데 이것저것 찾다 각 언어 서버별 I/O 처리 속도 비교하는 재밌는 글.

반응형