0Pricing
Java Academy · 강의

병목 식별

최적화하기 전에 측정합니다

병목 식별은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

측정하고 추측하지 마세요

성능 개선의 첫 번째 원칙은 최적화하기 전에 측정하는 것입니다.

Java 프로그램이 어디에서 시간을 소비하는지에 대한 직감은 대개 틀립니다. 실행 중 컴파일러, 가비지 컬렉터, 캐싱 때문에 막연한 추측만으로는 정확히 판단할 수 없습니다. 프로파일링으로 실제 병목을 찾고, 그 부분을 수정하세요.

병목이란

병목은 시스템 전체의 처리량이나 지연 시간을 제한하는 부분입니다.

다른 부분을 최적화해도 눈에 띄는 이점이 없습니다. 암달의 법칙은 이를 명확하게 보여 줍니다. 시간의 90%가 하나의 메서드에서 소요된다면 나머지 10%를 아무리 빠르게 만들어도 개선 폭은 11%를 넘을 수 없습니다.

지연 시간과 처리량

무엇을 최적화할지 먼저 결정하세요.

  • 지연 시간 — 요청 하나가 처리되는 데 걸리는 시간입니다.
  • 처리량 — 초당 처리할 수 있는 요청 수입니다.

두 목표는 서로 상충합니다. 일괄 처리는 처리량을 높이지만 요청 하나의 지연 시간을 늘릴 수 있습니다. 조정하기 전에 목표를 명확히 하세요.

벽시계 시간 측정

가장 단순한 측정 방법은 System.nanoTime()을 사용해 코드 블록 전후의 벽시계 시간을 재는 것입니다.

간단한 타당성 확인에는 유용하지만, 적시 컴파일 예열, 가비지 컬렉션 일시 중지, 운영 체제 스케줄링에 따른 변동이 포함됩니다. 따라서 단일 측정값은 주의해서 해석하세요.

public class Main {
    public static void main(String[] args) {
        long start = System.nanoTime();
        long sum = 0;
        for (int i = 0; i < 10_000_000; i++) sum += i;
        long elapsed = System.nanoTime() - start;
        System.out.println("Sum: " + sum);
        System.out.println("Elapsed ms: " + (elapsed / 1_000_000.0));
    }
}

적시 컴파일 예열에 주의하세요

Java는 바이트코드를 해석하기 시작한 다음, 자주 실행되는 메서드를 적시 컴파일러로 네이티브 코드로 컴파일합니다.

따라서 메서드의 첫 실행은 이후 실행보다 훨씬 느립니다. 단순한 측정 반복문은 대부분 예열 시간만 측정하게 됩니다. 실제 성능 측정은 먼저 예열한 다음 안정 상태를 측정하며, JMH가 바로 이 작업을 대신해 줍니다.

CPU 중심과 IO 중심

병목의 유형을 분류하세요.

  • CPU 중심 — 스레드가 계산 작업으로 바쁘고 코어가 포화된 상태입니다.
  • IO 중심 — 스레드가 디스크, 네트워크 또는 데이터베이스를 기다리는 상태입니다.

프로파일러는 이를 'CPU 실행 중' 시간과 '차단 또는 대기 중' 시간으로 구분합니다. 해결 방법은 완전히 다릅니다. 더 빠른 알고리즘을 사용하거나 동시성을 높이고 왕복 횟수를 줄여야 합니다.

샘플링과 계측

프로파일링에는 두 가지 전략이 있습니다.

  • 샘플링 — 주기적으로 호출 스택을 수집합니다. 오버헤드가 낮지만 통계적인 결과를 제공합니다.
  • 계측 — 모든 메서드에 카운터를 삽입합니다. 정확하지만 부담이 크고 측정 시간을 왜곡할 수 있습니다.

운영 환경에서는 Java Flight Recorder와 같은 오버헤드가 낮은 샘플링을 선호하세요.

메모리 병목

계산보다 실제 비용이 할당에 있는 경우가 많습니다. 객체를 과도하게 생성하고 폐기하면 가비지 컬렉션이 자주 발생하여 CPU를 빼앗고 일시 중지를 추가합니다.

할당률과 가비지 컬렉션 시간을 확인하세요. 자주 실행되는 반복문에서 할당을 줄이는 것이 산술 연산을 미세하게 조정하는 것보다 효과적인 경우가 많습니다.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Allocation-heavy: a new String each iteration
        List<String> garbage = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            garbage.add("item-" + i);
        }
        System.out.println("Allocated " + garbage.size() + " strings");
        System.out.println("In a hot loop, this churn drives GC pressure");
    }
}

스택 최상위 찾기

샘플링 프로파일러는 CPU 스택에 얼마나 자주 나타났는지를 기준으로 순위를 매긴 메서드 목록을 생성합니다. 이것이 자체 시간입니다.

목록의 최상위 메서드가 후보입니다. 하지만 해당 메서드가 핵심 경로에 있는지 확인하세요. 백그라운드 기록기에서 실행되는 메서드는 자주 실행되더라도 사용자에게 보이는 지연 시간에는 영향을 주지 않을 수 있습니다.

기준선 설정

무언가를 변경하기 전에 실제와 비슷한 부하에서 기준 측정값을 기록하세요.

변경할 때마다 다시 측정하고 비교하세요. 기준선이 없으면 최적화가 효과가 있었는지 증명할 수 없으며, 많은 '최적화'가 오히려 성능을 악화시킵니다. 한 번에 한 가지씩만 변경하세요.

현실적인 부하에서 프로파일링하기

유휴 상태의 노트북에서 발견한 병목이 운영 환경에서 문제를 일으키는 병목과 같지는 않을 수 있습니다.

  • 대표적인 데이터 크기와 동시성을 사용합니다.
  • 사용자에게 실제로 중요한 작업 부하를 재현합니다.

합성 마이크로 테스트는 규모가 커지면 중요하지 않은 메서드를 가리킬 수 있습니다. 실제로 문제가 발생하는 곳을 프로파일링하십시오.

빠른 확인

Java 메서드를 한 번만 단순하게 System.nanoTime()으로 측정한 결과가 오해를 불러일으키는 경우가 많은 이유는 무엇입니까?

요약

체계적으로 병목을 찾는 방법:

  • 최적화하기 전에 측정합니다. 직관은 자주 틀립니다.
  • 목표를 정합니다. 지연 시간인지 처리량인지 선택합니다.
  • CPU 작업 중심인지 IO 작업 중심인지 분류하고, 가비지 컬렉션과 할당을 관찰합니다.
  • 오버헤드가 낮은 샘플링 프로파일러를 우선 사용합니다.
  • JIT 준비 시간을 주의하고, 기준선을 설정한 뒤 한 번에 한 가지만 변경합니다.

자주 묻는 질문

“병목 식별” 강의는 무료인가요?

네 — “병목 식별” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“병목 식별”에서 뭘 배우나요?

최적화하기 전에 측정합니다 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“병목 식별” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 병목 식별
  2. Java Flight Recorder
  3. JDK Mission Control로 분석
  4. 자주 사용하는 JVM 튜닝 플래그
← Java Academy(으)로 돌아가기