JVM 모니터링과 툴링 Optimizing Java #5

BaekGwa·2024년 8월 26일

Optimizing Java

목록 보기
5/5

JVM 모니터링과 툴링

  • JVM은 성숙한 실행 플랫폼으로, 실행중인 애플리케이션을 인스트루먼테이션, 무니터링, 관측하는 다양한 기술을 제공합니다.
  • 다음은 이런 종류의 툴에 쓰이는 몇가지 중요한 기술입니다.
    • 자바 관리 확장 Java Management Extensions (JMX)
    • 자바 에이전트 Java agent
    • JVM 툴 인터페이스 JVM Tool Interface (JVMTI)
    • 서비스빌리티 에이전트 Serviceablilty Agent (SA)
  • 간단하게 설명하고, 추후에 코드 혹은 툴을 직접 소개할 수 있으면 진행 하겠습니다.

JMX

  • JMX는 JVM와 그 위에서 동작하는 애플리케이션을 제어하고 모니터링 하는 강력한 벙용 툴입니다.
  • 메서드를 호출하고 매개변수를 바꿀 수 있습니다.

자바 에이전드

  • 자바 언어로 작성된 툴 컴포넌트로, java.lang.instrument 인터페이스로 메서드 바이트코드를 조작 합니다.
  • 에이전트는 다음과 같이 JVM에 시작 플래그를 추가해서 설치합니다.

    -javagaent:<에이전트 JAR 파일이 위치한 경로>=<옵션>

JVMTI

  • JVMTI는 JVM의 네이티브 인터페이스이기 때문에, JVMTI를 사용하는 에이전트는 C/C++ 같은 네이티브 컴파일 언오로 작성해야 합니다.
  • JVM 이벤트를 모니터링 하며 알림을 받을 수 있도록 만든 통신 인터페이스이다.

    -agentlib:<에이전트 라이브러리명>=<옵션>
    -agentpath:<에이전트 경로>=<옵션>

SA

자바 객체, 핫스팟 자료 구조 모두 표출 가능한 API와 툴을 모아놓은 것 입니다.

  • SA를 이용하면 대상 JVM에서 코드를 실행할 필요가 없다.
  • 핫스팟 SA는 심볼 룩업 같은 기본형을 이용하거나, 메모리를 읽는 방식으로 디버깅 합니다.

VisualVM

  • VisualVM은 JMX의 대표적인 툴이다.
  • JDK 9 이상에서는 Default로 지원하지 않기때문에, 별도의 설치가 필요하다. [링크](https://visualvm.github.io

실행화면

실행 후, 좌측 Applications 에서 모니터링 할 프로그램을 선택하여 해당 프로그램의 모니터링을 시작 합니다.

  • VisualVM은 JVM 어태치 메커니즘을 이용해실행 프로세스를 실시간 모니터링 합니다.
  • VisualVM은 다섯가지 탭을 기본 제공하빈다.
    • 개요
      • 자바 프로세스에 관한 요약 정보를 표시합니다. 프로세스에 전달한 전체 플래그와 시스템프로퍼티, 그리고 실행중인 자바 버전도 명시됩니다.
    • 모니터
      • CPU, 힙 사용량 등 JVM을 고수준에서 원격 측정한 값들이 표시됩니다.
    • 스레드
      • 실행 중인 애플리케이션 각 스레드가 시간대별로 표시 됩니다.
      • 스레드별 상태와 짧은 변화 추이를 보면서 필요시 스레드 덤프를 뜰 수 있습니다.
    • 샘플러 및 프로파일러
      • cpu 및 메모리 사용률에 관한 단순 샘플링 결과가 표시됩니다.

간단한 모니터링 장면

  • 이미 가지고있는 Spring Boot 프로젝트를 활용하여 VisualVM을 실행하여 상태를 모니터링 해보겠다.
@RestController
@RequiredArgsConstructor
@RequestMapping
@Slf4j
public class StockLogController {

	~~ 기존 코드 ~~
    
	@Operation(summary = "테스트용 멀티 스레드 다수 생성 api", description = "테스트")
    @GetMapping
    public BaseResponse<Void> test() {
        ThreadPoolExecutor es = new ThreadPoolExecutor(100, 100, 0, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(100));
        try{
            for(int i=0; i<100; i++) {
                es.submit(new TestThread());
            }
        } finally {
            es.shutdown();
        }

        return new BaseResponse<>();
    }

    private static class TestThread implements Callable<String>
    {
        @Override
        public String call() throws Exception {
            Thread.sleep(10000);
            return "OK";
        }
    }
  • 해당 컨트롤러를 호출하게 되면, Thread가 100개 생성되고, 그 스레드는 10초식 Sleep (즉, Waiting 상태)이 되도록 하였다.

실행전

실행 후

profile
현재 블로그 이전 중입니다. https://blog.baekgwa.site/

0개의 댓글