generated from Learning-Is-Vital-In-Development/study-template
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
62 changed files
with
5,682 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
* @dojinyou | ||
* @Learning-Is-Vital-In-Development/24-optimizing-java-1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# 1.2 자바 성능 개요 | ||
|
||
자바는 처음에 **생산성을 높히고** **성능을 다소 희생**하는 걸 목표로 탄생함. | ||
|
||
JVM은 개발자가 직접 하부 리소스를 관리하는 대신 Garbage Collector 같은 서브시스템을 사용해 대신 리소스 관리를 해줌. | ||
따라서 JVM은 런타임 동작이 다소 복잡하다는 특징이 있다. | ||
|
||
자바 성능의 특징 | ||
- JVM 성능 측정값은 정규 분포를 따르지 않아서 기초 통계 기법으로 측정 결과 제대로 처리하기 힘듦 | ||
- 측정하는 행위 자체가 오버헤드를 일으켜서 너무 자주 샘플링하면 성능 결과 수치에 영향을 미칠 수 있음 | ||
|
||
# 1.3 성능은 실험과학이다 | ||
|
||
JVM 성능 튜닝을 위해서는 여러 조건에서 실험을 통해 원하는 결과를 도출해야 한다. | ||
|
||
1. 원하는 결과를 정의 | ||
2. 기존 시스템 측정 | ||
3. 요건 충족을 위해 해야 하는 일 정하기 | ||
4. 개선 활동 추진 | ||
5. 다시 테스트 | ||
6. 목표 달성 됐는지 판단한다. | ||
|
||
**예시** | ||
1. 100RPS의 부하 상황에서 99%의 응답시간에 대해 100ms 이하를 만족하고 싶다. | ||
2. 현재 시스템을 측정하면 50RPS 정도에서 벌써 100ms를 초과한다. | ||
3. APM 툴로 병목 구간 분석해보니 DB 조회에서 시간이 많이 걸린다. | ||
4. **쿼리 최적화**, **인덱스 세팅**, 데이터 특성에 따라 **캐시 도입** 등의 개선 작업 수행 | ||
5. 다시 성능 테스트 | ||
6. 100RPS에서 100ms 이하를 충분히 달성함으로 개선 성공 | ||
|
||
# 1.4 성능 분류 | ||
|
||
### 처리율 | ||
- 시스템이 수행 가능한 작업 비율을 나타낸다. 가장 많이 사용되는 지표는 **TPS**(Transaction Per Second) | ||
- TPS를 측정할때는 테스트를 진행한 서버 스펙, 스케일 아웃 상태 등을 명확히 해야한다. | ||
- TPS를 측정하는 테스트는 항상 동일한 작업 단위를 대상으로 수행해야 한다. | ||
### 지연 | ||
- 1초에 100리터를 흘려보내는 수도관에서 처리율은 1초에 처리되는 물의 부피(100L) | ||
- 지연시간은 수도관의 길이를 의미한다. 즉, 작업의 종단 시간을 의미함 | ||
|
||
### 용량 | ||
- 시스템이 동시 처리 가능한 작업 단위의 개수 | ||
### 사용률 | ||
- 시스템 리소스를 효율적으로 활용하도록 만드는게 성능 분석에서 중요한 부분 | ||
- 사용률은 어떤 작업이냐에 따라 달라질 수 있다. | ||
- CPU Intensive한 작업은 CPU 사용률 높고 Memory 사용률 낮음 | ||
### 효율 | ||
- 효율은 처리율을 리소스 사용률로 나눈 값 | ||
- 같은 처리율을 더 적은 리소스 사용률로 달성할 수 있다면 효율적임 | ||
|
||
### 확장성 | ||
- 리소스 추가에 따른 처리율 변화는 시스템/어플리케이션의 확장성을 가늠하는 척도 | ||
- 리소스 n배 증가에 따라 처리율이 n배 증가하면 완전한 선형 확장이다. 하지만 현실에서는 가능성 적음. | ||
- 지속적으로 스케일 아웃을 하다보면 한계점에 도달하게 됨. | ||
|
||
### 저하 | ||
- 트래픽의 증가로 시스템이 부하를 받으면 성능 저하가 발생할 수 있음. | ||
- 현재 리소스 사용률에 따라 다르다. 리소스 덜 사용하고 있으면 저하는 덜 발생하고, 시스템 풀 가동 상태면 처리율은 증가하지 않고 성능 저하 급격히 발생. | ||
|
||
### 측정값 사이의 연관 관계 | ||
|
||
각각의 측정값은 서로 영향을 줄 수 있다. | ||
|
||
**JIT Compiler 예시** | ||
|
||
JIT Compiler가 네이티브 코드로 컴파일해서 코드 캐시에 저장하는 기준은 메서드가 호출되서 인터프리팅 된 횟수이다. | ||
따라서 부하가 적어서 메서드가 별로 호출 안되면 기준을 불충족해서 계속 인터프리팅을 하게 되고, 일정 부하를 넘어서야 컴파일 된다. | ||
|
||
|
||
# 1.5 성능 그래프 읽기 | ||
|
||
<img width="500" alt="스크린샷 2024-01-10 오후 6 24 43" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/a591d14f-0001-4ce0-a496-df42706f0575"> | ||
|
||
부하가 증가하면서 예기치 않게 지연이 발생하는 그래프를 **성능 엘보**라고 한다. | ||
|
||
**실제 발생 가능할 만한 상황** | ||
- 커넥션풀/쓰레드풀이 고갈되서 더이상 요청을 처리하지 못할때 | ||
|
||
무상태 환경에서 스케일 아웃을 하면 준-선형적 그래프를 그릴 수 있음 | ||
|
||
### 암달의 법칙 | ||
|
||
프로세스 내에는 순차 처리가 필요한 부분이 반드시 있기에 아무리 병렬 처리를 해도 더이상 성능 향상이 되지 않는 **한계점이 존재**한다는 법칙 | ||
|
||
90% 병렬화 그래프는 **10% 순차 처리**를 의미한다. 10%만 순차처리를 해도 프로세서 개수를 1024개로 늘린 상황에서 **10배 이상은 시간 단축이 되지 않는다**. 즉 한계에 부딫힘 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# [1장 성능과 최적화] | ||
|
||
### 1.1 자바 성능: 잘못된 방법 | ||
|
||
- 자바 초창기에 메서드 디스패치 성능은 최악이었다. 그래서 메서드를 잘게 나누지 말고 하나의 덩치 큰 메서드로 작성하는 게 좋다고 권고하는 개발자도 존재했다. 물론 시간이 지나면서 가상 디스패치 성능은 엄청나게 좋아졌고 특히 최신 자바 가상 머신에서는 자동 인라이닝 덕분에 가상 디스패치조차 대부분의 호출부에서 사라지게 되었기에 모든 코드를 한 메서드에 넣으라는 코드는 현대 JIT 컴파일러와는 어울리지 않게 되었다. | ||
- 메서드 디스패치 : 메서드 실행 시 실제 호출할 메서드를 결정하는 프로세스 | ||
- 자바 코드가 실행되는 속도는 매우 변화무쌍하며 전적으로 코드를 실행하는 하부(겉으로 드러나지 않는 내부 구현 코드) JVM에 따라 다르다. 따라서 오래 전 작성한 자바 코드도 재컴파일 없이 최신 jvm에서 실행하면 더 빨리 작동될 수 있다. | ||
|
||
### 1.2 자바 성능 개요 | ||
|
||
- 실용성을 추구하는 자바 플랫폼의 성격은 여러 방면에서 드러난다. | ||
- 서브시스템이 그 예이다. | ||
- 개발자가 일일이 용량을 세세하게 관리하는 부담을 덜어주고, 대신 저수준으로 제어 가능한 일부 기능을 포기하자는 발상이다. | ||
- JVM 전반에 걸쳐 등장하는 관리되는 서브시스템은 그 존재 자체로 jvm 애플리케이션의 런타임 동작에 복잡도를 유발한다. | ||
|
||
### 1.3 성능은 실험과학이다. | ||
|
||
- 대부분 최신 sw 시스템이 그렇듯, 자바/JVM SW 스택 역시 아주 복잡하다. | ||
- 이렇게 복잡한 지경까지 이른 건 무어의 법칙과 그로 인한 하드웨어 용량의 전무후무한 발전 때문일 것이다. | ||
- 무어의 법칙 : 반도체 집적 회로의 성능이 24개워람다 2배로 증가한다는 법칙 | ||
|
||
### 1.4 성능 분류 | ||
|
||
- 성능 지표는 성능 분석의 어휘집이자, 튜닝 프로젝트의 목표를 정량적인 단위로 표현한 기준이다. | ||
- 실제로는 어느 한 지표를 최적화하면 다른 지표들이 약화되는 경우도 흔하다. | ||
|
||
1.4.1 처리율 | ||
|
||
- 처리율은 서브시스템이 수행 가능한 작업 비율을 나타낸 지표이다. 보통 일정 시간 동안 완료한 작업 단위 수로 표시한다. (초당 처리 가능한 트랜잭션 수) | ||
|
||
1.4.1 지연 | ||
|
||
- 하나의 트랜잭션을 처리하고 그 결과를 반대편 수도관 끝까지 바라볼 때까지 소요된 시간을 의미한다. | ||
|
||
1.4.1 용량 | ||
|
||
- 시스템이 보유한 작업 병렬성의 총량, 즉 시스템이 동시 처리 가능한 작업(트랜잭션) 단위 개수를 의미한다. | ||
|
||
1.4.1 사용률 | ||
|
||
- 성능 분석 업무 중 가장 흔한 태스크는 시스템 리소스를 효율적으로 관리하는 것이다. | ||
- 사용률은 워크로드에 따라서 리소스별로 차이가 있을 수 있다. | ||
- 예시로 계산 집약적 워크로드(그래픽 처리, 암호화)를 주면 cpu 사용률은 100%에 육박하지만 메모리 사용률은 얼마 안나온다. | ||
|
||
1.4.1 효율 | ||
|
||
- 전체 시스템의 효율은 처리율을 리소스 사용률로 나눈 값으로 측정한다. | ||
- 같은 처리율을 더 많은 리소스를 쏟아부어야 달성할 수 있다면 분명 효율이 낮은 것이다. | ||
|
||
1.4.1 확장성 | ||
|
||
- 처리율이나 시스템 용량은 처리하는 데 끌어 쓸 수 있는 리소스에 달려 있다. | ||
- 리소스 추가에 따른 처리율 변화는 시스템/애플리케이션의 확장성을 가늠하는 척도이다. | ||
|
||
1.4.1 저하 | ||
|
||
- 시스템을 덜 사용하고 있으면 측정 값이 느슨하게 변하지만, 시스템이 풀 가동된 상태면 처리율이 더는 늘어나지 않는, 즉 지연이 증가하는 양상을 띈다. | ||
- 이러한 현상을 부하 증가에 따른 저하라고 한다. | ||
|
||
1.4.1 측정값 사이의 연관 관계 | ||
|
||
- JIT 컴파일 대상이 되는 메서드는 인터프리티드 모드로 실행되어야 한다. 따라서 부하가 적을 경우 핵심 메서드가 인터프리티드 모드의 늪에서 허우적거릴 가능성도 있지만, 부하가 많아 메서드 호출 빈도가 증가하면 jit 컴파일 대상이 될 수도 있다. | ||
- 결국 같은 메서드지만 나중에 호출하는 게 처음보다 훨씬 더 빨리 실행된다. | ||
|
||
### 1.5 성능 그래프 읽기 | ||
|
||
- 부하가 증가하면서 예기치 않게 저하가 발생한 그래프의 형태를 성능 엘보라고 한다. | ||
- 그와 반대로 선형적으로 처리율이 확장되는 결과는 환경이 극단적으로 순조로울 때(서버 하나에 세션 어피니티가 필요벗는 무상태 프로토콜을 확장하는 경우)나 가능하다. | ||
- 진 암달이 발표한 암달의 법칙이 나온다. 암달에 따르면 근본적으로 확장성에는 제약이 따른다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
## CH1 | ||
|
||
### 1.4 성능 분류 | ||
|
||
- 처리율 | ||
- (서브)시스템이 수행 가능한 직업 비율 | ||
- 일정 시간 동안 완료한 작업 단위 수로 표시(ex: 초당 처리 가능한 트랜잭션 수) | ||
- 지연 | ||
- ex: 하나의 트랜잭션을 처리하고 그 결과를 반대편 수도관 끝에서 바라볼 때까지 소요된 시간 | ||
- 용량 | ||
- 시스템이 보유한 작업 병렬성의 총량 | ||
- 시스템이 동시 처리 가능한 작업의 단위(즉, 트랜잭션) 개수 | ||
- 사용률 | ||
- 시스템 리소스를 효율적으로 활용하는 것이 중요하다. (단순 사용률이 높은게 실제 작업을 처리하는데 사용되는지 확인 필요) | ||
- 워크로드에 따라 (무슨 작업인지) 리소스 별로 들쑥날쑥 할 수 있다. | ||
- 효율 | ||
- 처리율/리소스 사용률 | ||
- 즉 같은 처리율이라도 적인 리소스를 사용해야한다. | ||
- 확장성 | ||
- 리소스 추가에 따른 처리율 변화는 시스템 및 어플리케이션의 확장서을 가능하는 척도 | ||
- 리소스를 투입한만큼 처리율이 변경되는 형태를 지향한다. | ||
- 저하 | ||
- 요청 개수 증가, 요청 접수 속도 증가 등 시스템이 부하를 받으면 지연, 처리율 측정값에 변화가 생긴다. | ||
- 사용률에 따라 변화가 다르다. 시스템이 풀가동이라면 처리율이 늘어나지 않는, 지연이 증가하는 향상을 띠는데 이를 부하 증가에 따는 저하라고 한다. | ||
|
||
### 1.5 성능 그래프 읽기 | ||
|
||
- 성능 엘보 | ||
- 부하기 증가하면서 어는 순간부터 지연의 기울기가 늘어나는 형태 |
Oops, something went wrong.