Virtual Threads 알아보기(3)

이월(0216tw)·2024년 5월 14일

가상스레드 스케줄링 방식

플랫폼 스레드는 OS 가 스케줄링을 하고 가상 스레드는 자바 런타임이 관리한다.

가상 스레드를 스케줄링 하는 방식

(1) 자바 런타임이 플랫폼 스레드 상 가상 플랫폼을 할당하거나 마운트한다.

(2) 그리고 나서 OS가 해당 플랫폼 스레드를 스케줄링한다. (이때 플랫폼 스레드를 carrier라고 부름)

(3) 일정 코드를 진행하는 가상스레드는 다시 carrier로부터 언마운트 된다. (보통 IO blocking 때 많이 발생)

(4) 그럼 언마운트 상태인 carrier는 또 다른 가상 스레드를 자바 런타임에 의해 마운트 되어 쓸 수 있게 된다.


pin처리한 가상스레드

carrier(가상스레드가 할당된 플랫폼스레드) 가 pin처리되어 있다면 블로킹 작업 동안에도 가상 스레드가 언마운트 되지 않는다.

pin 처리 되는 경우 (pin이란 고정됨을 의미함)

(1) 가상스레드가 synchronized 블록 및 메서드에서 실행되고 있을 때
(2) 가상스레드가 native 메서드나 외부 메서드를 실행할 때

위 경우에는 블로킹 작업이 있어도 언마운트 및 다른 가상 스레드에 할당이 아니라 계속 특정 플랫폼 스레드와 연결(마운트) 되어 있는 것이다.
이 경우 가상 스레드의 성능 및 확장성에 영향을 미칠 수 있다.

오래된 pin 처리를 막으려면?

(1) synchronized 블록 및 메서드가 자주 실행되지 않게 코드를 개선하거나 설계를 변경한다.
(2) 잠재적으로 긴 I/O 작업을 ReentrantLock과 같은 잠금(lock) 메커니즘으로 보호한다.

ReentrantLock이란? TODO 작성예정


가상스레드 디버깅 하기

가상스레드도 기존 스레드처럼 디버깅을 할 수 있다.
JDK Flight Recorder 나 jcmd 툴을 이용해 본인의 앱상에서 가상 스레드를 관찰할 수 있다.

JDK Flight Recorder (JDF) 로 디버깅

  • jdk.VirtualThreadStart
    가상 스레드가 시작될 때 발생하는 이벤트 (dafault - 비활성화)
  • jdk.VirtualThreadEnd
    가상 스레드가 종료될 때 발생하는 이벤트 (default - 비활성화)
  • jdk.VirtualThreadPinned
    가상 스레드가 특정 플랫폼 스레드에 pin되어있을 때 발생하는 이벤트 (default - 활성화)
    (특정 캐리어 스레드가 다른 가상 스레드를 마운트 못하면 확장성이 떨어질 텐데 이를 확인 가능)
  • jdk.VirtualThreadSubmitFailed
    가상 스레드가 시작/재실행(submit)이 실패하는 경우 나타나는 이벤트(default - 활성화)

위와 같은 이벤트를 출력하기 위해 아래 명령어를 실행한다.

jfr print --events //jfk 툴로 이벤트를 출력하겠다. 

jdk.VirtualThreadStart,jdk.VirtualThreadEnd,jdk.VirtualThreadPinned,jdk.VirtualThreadSubmitFailed recording.jfr

//출력할 대상은 ..Start , ..End , ..Pinned , ..Failed 이며 recording.jfr 에 기록된다. 

jcmd 스레드 덤프로 디버깅

jcmd <PID> Thread.dump_to_file -format=text <file>
jcmd <PID> Thread.dump_to_file -format=json <file>

위 명령어를 통해 생성된 스레드 덤프에는 IO 블로킹된 가상 스레드와 ExecutorService 인터페이스로 생성된 가상 스레드 등 "특정 유형의 가상 스레드" 에 대한 정보가 포함된다.

단, 객체 주소 , 잠금 , JNI 통계 , 힙 통계 등의 다른 정보등은 포함하지 않는다.
(전통적인 스레드 덤프는 위 정보도 보여주는데 반해 jcmd는 정보가 제한적이다.)

profile
#SQLD강사 #AI개발 #AI강사 #개발자 개발도 하고 강의도 하지만 고민을 제일 많이 합니다

0개의 댓글