Skip to main content

1. 성능과 최적화

성능 분석은 경험주의와 인간 심리학이 어울러진 부분입니다.

자바 성능 : 잘못된 방법#

과거 자바 초창기에는 메서드 디스패치 성능은 최악이였습니다. 그래서 메서드를 잘게 나누지 말고, 하나의 덩치 큰 메서드로 작성하는게 좋다라는 의견이 있었습니다.

그러나 시간이 지남에 따라 가상 디스패칭 성능이 엄청 좋아졌고, JVM에서는 자바 인라이닝 덕분에 가상 디스패치 조차 대부분의 호출에서 사라지게 되었습니다. 따라서 모든 코드를 한 메서드에 넣어서 작성하는 코드는 퇴물이 되어서 사라졌습니다.

시대에 따라 이렇게 성능 팁을 나열하는 것이 아니라 여러 가지 단면을 확인할 필요가 있습니다.

  • 전체 소프트웨어 수명주기의 성능 방법론
  • 성능과 연관된 테스트 이론
  • 측정, 통계, 툴링(tooling) : 도구 선정
  • (시스템 + 데이터) 분석 스킬
  • 하부 기술과 매커니즘 : 장치, 수단

최적화하는 휴리스틱과 각종 코드 수준의 테크닉은 끝부분에서 작성합니다. 다만, 모든 최적화 기법에는 개발자가 사용하기 전에 알아둬야하는 함정과 트레이드 오프가 있기 때문에 신경써야합니다.

일반적인 원칙은 아래와 같습니다.

  • JVM을 더 빨리 작동시키는 마법 스위치 같은 것은 없습니다.
  • 자바를 더 빨리 실행하게 만드는 팁, 트릭은 없습니다.
  • 사람들이 모르는 비밀 알고리즘은 없습니다.

자바 성능 개요#

자바는 실용적인 언어입니다. 그러한 대표적인 특징으로 서브 시스템을 예시로 들 수 있습니다.

  • 개발자가 일일이 용량을 세세하게 관리하는 부담을 덜여주고, 주수준으로 제어 가능한 일부 기능을 포기합니다.
  • JVM이 가비지 수집 서브시스템 형태로 메모리를 자동 관리하기 덕분에 프로그래머는 수동으로 메모리를 의식해서 개발할 필요가 없습니다.
  • 런타임 동작에 복잡도를 유발합니다. (JVM에 의해)

다만, 자바 성능 측정을 위해서 잘못된 판단을 할 수 있으므로 조심해야합니다.


성능은 실험과학이다#

JVM 소프트웨어 스택은 아주 복잡합니다. 다만, 여러 성능 이슈가 발생할 수 있으나 최상의 성능을 제공하기 위해서는 어느 수준 이상의 스킬과 경험이 필요합니다.

JVM 성능 튜닝은 기술, 방법론, 정량적 측정값, 툴을 망라한 개념입니다. 일반적으로 아래와 같은 순서로 진행합니다.

  • 원하는 결과를 정의합니다.
  • 기존 시스템을 측정합니다.
  • 요건을 충족시키려면 무슨 일을 해야 할지 정합니다.
  • 개선 활동을 추진합니다.
  • 다시 테스트합니다.
  • 목표가 달성됐는지 판단합니다.

성능 분석은 통계치에 큰거해 적절히 결과를 처리하는 활동입니다. 이에 대한 자세한 내용은 5장에서 이야기합니다.


성능 분류#

성능 지표는 아래와 같습니다.

  • 처리율
  • 지연
  • 용량
  • 사용률
  • 확장성
  • 저하

다만 이를 수행할 때마다, 좋아야 2~3개 지표가 개선이 되고, 한 지표를 개선했다가 다른 지표들이 악화되는 경우도 있습니다.

처리율#

처리율(throughput)서브 시스템이 수행 가능한 작업 비율을 나타낸 지표입니다. (일정 시간동안 완료한 작업 단위 수)

  • 플랫폼에 대한 내용도 기술해야합니다. (HW, OS, SW 스택, 단일 서버인지 혹은 클러스터 환경인지)

지연#

성능 지표를 일종의 수도 패관에 빗대어 설명가능한데, 지연(latency)은 수도관 자체의 길이를 의미합니다. 하나의 트랜잭션을 처리하고 그 결과를 반대편 수도관 끝에서 바라볼 때까지 소요된 시간입니다.

용량#

용량(capacity)는 시스템이 보유한 작업 병렬성의 총량, 즉 시스템이 동시 처리 가능한 작업 단위(트랜잭션) 개수를 의미합니다.

시스템에 동시 부하가 증가할수록 처리율도 당연히 영향을 받습니다. 이러한 이유로 보통 용량은 어떤 처리율 또는 지연 값을 전제로 가능한 처리량을 표시합니다.

사용률#

성능 분석 업무 중 가장 흔한 태스크는 시스템 리소스를 효율적으로 활용하는 것입니다. CPU 리소스가 실제 작업 단위를 처리하는데 쓰여야합니다.

사용률(utilization)은 워크로드에 따라서 리소스별로 들쑥날쑥합니다.

효율#

전체 시스템의 효율(efficiency)처리율을 리소스 사용률로 나눈 값으로 측정합니다.

확장성#

처리율이나 시스템 용량은 처리하는데 끌어 쓸 수 있는 리소스에 달려있습니다. 리소스 추가에 따른 처리율 변화는 시스템/애플리케이션의 확장성(scalability)을 가늠하는 척도입니다. 시스템 확장성은 리소스를 투입한 만큼 처리율이 변경되는 형태를 지향합니다.

그러나 일반적으로 확장성은 여러 가지 인자들의 영향을 받습니다. 리소스를 어느 정도까지 늘리면 선형적으로 확장되지만, 대부분 부하가 높아지면 한계점에 봉착합니다.

저하#

요청 개수가 증가하거나 접수 속도가 증가하면, 시스템이 더 많은 부하를 받아 지연과 처리율 측정값에 변화가 생깁니다.

변화는 사용률에 따라 다릅니다. 시스템을 덜 사용하고 있으면 측정값이 느슨하게 변하지만, 시스템이 풀 가동된 상태면 처리율이 더 늘어나지 않는 양상을 가집니다. 이러한 현상을 부하 증가에 따른 저하(degradation)이라고 합니다.

측정값 사이의 연관 관계#

다양한 성능 측정값은 어떤 식으로 연결되어 있습니다.

  • 부하에 따라 여러 측정값이 요동칠 수 있습니다.
  • 확장성과 저하는 부하가 증가함에 변화됩니다.

성능 그래프 읽기#

부하가 증가하면서 예기치 않은 저하(지연)이 발생하는 그래프를 확인할 수 있으며 이러한 형태를 보통 성능 엘로(performance elbow) 입니다.

performance elbow

이와는 반대로 장비 추가에 따라 거의 선형으로 처리율이 확장되는 운좋은 케이스가 있습니다. 다만 대부분 암달의 법칙과 비슷합니다.

암달의 법칙

GC 이후 힙 사용량은 아래와 같은 것이 좋습니다.

image

그러나 문제가 있는 그래프는 아래와 같습니다. (피보나치를 실행한 그래프)

image

Last updated on