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
6 changed files
with
269 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
marp: true | ||
--- | ||
|
||
# 1. 성능과 최적화 | ||
|
||
## 최 혁 | ||
|
||
--- | ||
|
||
# 자바 성능 개요 | ||
|
||
- 자바는 일을 하려고 만든 지극히 실용적인 언어이기에 개발 생산성을 위한 성능 희생이 있다. | ||
- managed subsystem을 통해 개발자가 관리해야 할 부담을 덜어준다.(ex. 메모리 관리) | ||
- 반대급부로, JVM 전반에 걸쳐 등장하는 managed subsystem은 그 존재 자체로 JVM 애플리케이션의 런타임 동작에 복잡도를 유발한다. | ||
- 환경이 복잡해 질수록 시스템을 개별적으로 떼어내 생각하기 어렵기에 자바 성능 측정값에 대한 판단은 조심해야 한다. | ||
- 성능을 측정하는 행위 자체도 오버헤드를 일으키기에 너무 자주 샘플링하거나 매번 결과를 기록하는 것 또한 성능 결과 수치에 영향을 미친다. | ||
|
||
--- | ||
|
||
# 성능 분류 | ||
|
||
### 처리율 | ||
|
||
> 시스템이 수행 가능한 작업 비율을 나타낸 지표로 보통 `일정 시간 동안 완료한 작업의 단위 수`로 표시한다. | ||
- ex) 초당 처리 가능한 트랜잭션 수 | ||
- 처리율이 실제 성능을 반영하는 의미 있는 지표가 되려면 수치를 얻은 플랫폼에 대한 내용(하드웨어 스펙 등)도 기술해야 한다. | ||
|
||
### 지연 | ||
|
||
> 예를 들어 1초에 100리터를 흘려보내는 `수도관 자체의 길이`이다. 즉, 하나의 트랜잭션을 처리하고 그 결과를 반대편 수도관 끝에서 바라볼 때까지 소요된 시간이다. | ||
--- | ||
|
||
### 용량 | ||
|
||
> 시스템이 보유한 작업 병렬성의 총량. 즉 `시스템이 동시 처리 가능한 작업 단위(트랜잭션)` 개수를 말한다. | ||
- 용량은 처리율과 밀접한 관련이 있다. | ||
- 보통 용량은 어떤 처리율 또는 지연 값을 전제로 가능한 처리량으로 표시한다. | ||
|
||
### 사용률 | ||
|
||
> 말 그대로 자원의 사용률이다. | ||
- 사용률은 워크로드에 따라 리소스별로 들쑥날쑥하다. | ||
- 계산 집약적 워크로드(그래픽 처리, 암호화)를 주면 CPU 사용률은 100%에 육박하지만, 메모리 사용률은 얼마 안 나온다. | ||
|
||
--- | ||
|
||
### 효율 | ||
|
||
> `처리율을 리소스 사용률로 나눈 값`이다. | ||
- 같은 처리율을 더 많은 리소스를 들여야 달성할 수 있다면 효율이 낮다고 할 수 있다. | ||
|
||
### 확장성 | ||
|
||
- 리소스 추가에 따른 처리율의 변화는 시스템/애플리케이션의 확장성을 가늠하는 척도이다. | ||
- 시스템 확장성은 궁극적으로 리소스를 투입한 만큼 처리율이 변경되는 것을 지향한다. | ||
- 현실적으로 클러스터를 2배 늘리면 트랜잭션 처리량도 2배로 늘리기는 어렵다. | ||
|
||
--- | ||
|
||
### 저하 | ||
|
||
> 시스템 사용률이 높을 때 부하가 증가하면 처리율이 더는 늘어나지 않는, 지연 현상이 발생하는데 이런 현상을 부하 증가에 따른 저하라 한다. | ||
### 측정값 사이의 연관 관계 | ||
|
||
- 다양한 성능 측정값은 어떤 식으로든 서로 연결되어 있다. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,82 @@ | ||
--- | ||
marp: true | ||
--- | ||
|
||
# 2. JVM 이야기 | ||
|
||
## 최 혁 | ||
|
||
--- | ||
|
||
# JVM | ||
|
||
- JVM은 스택 기반 인터프리터 머신이다. | ||
- 물리적인 CPU 하드웨어인 레지스터는 없지만 일부 결과를 실행 스택에 보관하며, 이 스택의 맨 위에 쌓인 값들을 가져와 계산한다. | ||
- JVM 인터프리터는 평가 스택을 이용해 중간값들을 담아두고 가장 마지막에 실행된 명령어와 독립적으로 프로그램을 구성하는 opcode를 하나씩 순서대로 처리하는 `while문 안의 switch문`이다. | ||
|
||
--- | ||
|
||
# 자바 애플리케이션 실행 | ||
|
||
1. 부트스트랩 클래스가 자바 런타임 코어 클래스를 로드한다. 부트스트랩 클래스로더는 다른 클래스로더가 나머지 시스템을 로드할 수 있게 최소한의 필수 클래스(java.lang.Object, Class 등)만 로드한다. | ||
2. 확장 클래스로더가 생성되고 클래스로더가 차례대로 작동한다. | ||
3. 애플리케이션 클래스로더가 생성되고 클래스패스에 위치한 유저 클래스를 로드한다. | ||
|
||
--- | ||
|
||
### 자바 컴파일러 | ||
|
||
- 자바 소스 코드를 자바 컴파일러(javac)를 이용해 컴파일한다.(전체 빌드 프로세스의 한 부분) | ||
- 자바 소스코드 -> .class 파일로 변환 | ||
|
||
### 바이트코드 | ||
|
||
- 바이트코드는 특정 컴퓨터 아키텍처에 특정하지 않은 중간 표현형(IR)이다. | ||
- 컴퓨터 아키텍처의 지배를 받지 않으므로 이식성이 좋다. | ||
- JVM은 클래스를 로드할 때 올바른 형식을 준수하고 있는지 검사한다. | ||
|
||
--- | ||
|
||
## opcode | ||
|
||
 | ||
|
||
--- | ||
|
||
### 핫스팟 | ||
|
||
- 썬 마이크로시스템즈는 핫스팟 가상 머신을 만들어 C/C++ 같은 언어에 필적할 만한 성능을 끌어냈다. | ||
- 핫스팟은 프로그램의 런타임 동작을 분석하고 성능에 가장 유리한 방향으로 영리한 최적화를 적용하는 가상 머신이다. | ||
|
||
### JIT 컴파일 | ||
|
||
- 자바 프로그램은 바이트코드 인터프리터가 가상화한 스택 머신에서 명령어를 실행하며 시작된다. | ||
- CPU를 추상화했기에 다른 플랫폼에서도 구동 가능하지만, 프로그램이 성능을 최대로 내려면 네이티브 기능을 활용해 CPU에서 직접 프로그램을 실행시켜야 한다. | ||
- 이를 위해 핫스팟은 프로그램 단위를 인터프리티드 바이트코드에서 네이티브 코드로 컴파일한다. -> `JIT(Just-in-Time) 컴파일` | ||
|
||
--- | ||
|
||
- 컴파일러가 해석 단계에서 수집한 추적 정보를 근거로 (핫스팟이) 최적화를 결정하는게 가장 큰 장점이다. | ||
- 최신 성능 최적화를 보려면 핫스팟 새 버전에서 자바 애플리케이션을 실행하는 것이 좋다. | ||
|
||
### JVM 메모리 관리 | ||
|
||
- C,C++등의 언어는 메모리 할당/해제 작업을 개발자가 직접 수행해야 하기에 메모리를 정확하게 계산해서 처리해야 하는 부담감이 있었다. | ||
- 자바는 Garbage Collection이라는 프로세스를 이용해 힙 메모리를 자동 관리하는 방식으로 해결했다. | ||
- Garbage Collection: JVM이 더 많은 메모리를 할당해야 할 때 불필요한 메모리를 회수하거나 재사용하는 프로세스 | ||
|
||
--- | ||
|
||
### 스레딩과 자바 메모리 모델(JMM) | ||
|
||
- 자바는 1.0부터 멀티스레드 프로그래밍을 기본 지원했기에 개발자가 언제든 실행 스레드를 새로 만들 수 있다. | ||
- 자바 환경도 JVM처럼 멀티스레드 기반이기에 성능 분석이 훨씬 힘들다. | ||
|
||
### JVM 구현체 종류 | ||
|
||
OpenJDK, Oracle Java(라이선스를 제외하고 OpenJDK간 아무런 차이도 없다), Zulu, IcedTea, Zing, J9, Avian, Android | ||
|
||
### JVM 모니터링과 툴링 | ||
|
||
- JMX: JVM과 그 위에서 동작하는 애플리케이션을 제어하고 모니터링하는 범용 툴 | ||
- 자바 에이전트: 자바 언어로 작성된 툴 컴포넌트로 java.lang.instrument 인터페이스로 메서드 바이트코드를 조작한다. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,115 @@ | ||
--- | ||
marp: true | ||
--- | ||
|
||
# 3. 하드웨어와 운영체제 | ||
|
||
## 최 혁 | ||
|
||
--- | ||
|
||
> 컴퓨터 성능 향상은 소프트웨어의 복잡도 향상으로 이어졌고, 그 결과 성능 향상을 꾀하려면 복잡한 기술에 의지해야 할 수밖에 없게 됐다. | ||
--- | ||
|
||
# 메모리 | ||
|
||
- 무어의 법칙에 따라 급증한 트랜지스터는 클록 속도를 높이는데 쓰였고, 이에 프로세스 속도가 매우 빨라졌다. | ||
- 하지만 시간이 갈수록 프로세서 코어의 데이터 수요를 메인 메모리가 맞추기 어려워졌다.(클록 속도와 액세스 속도의 차이 때문에 PU가 논다) | ||
- 이에 CPU 캐시가 고안되었다. 자주 액세스하는 메모리 위치는 CPU가 CPU 캐시에 보관하는 아이디어이다. | ||
- 메모리에 있는 데이터를 캐시로 가져오거나 캐시한 데이터를 메모리에 다시 쓰는 작업은 캐시 일관성 프로토콜이라는 방법으로 해결한다. | ||
|
||
--- | ||
|
||
# 최신 프로세서 특성 | ||
|
||
- `변환 색인 버퍼(TLB)`는 여러 캐시에 쓰이는 장치로 가상 메모리 주소를 물리 메모리 주소로 매핑하는 페이지 테이블의 캐시 역할을 수행한다. | ||
- `분기 예측`은 프로세서가 조건 분기하는 기준값을 평가하느라 대기하는 현상을 방지한다. | ||
- 따라서 조건문을 평가하는 동안 발생 가능성이 큰 브랜치를 미리 결정하는 휴리스틱을 만들어 미리 추측한 결과를 바탕으로 파이프라인을 채운다. | ||
|
||
--- | ||
|
||
# 운영체제 | ||
|
||
> 모든 리소스는 한정돼 있고 프로세스는 저마다 리소스를 더 차지하려고 하기에 골고루 나누어줄 중앙 시스템이 있어야 한다. | ||
- 메모리 관리 유닛(MMU)을 통한 `가상 주소 방식`과 `페이지 테이블`은 메모리 액세스 제어의 핵심으로서, 한 프로세스가 소유한 메모리 영역을 다른 프로세스가 함부로 훼손하지 못하게 한다. | ||
|
||
### 스케줄러 | ||
|
||
- 프로세스 스케줄러는 실행 큐(스레드나 프로세스가 CPU 차례를 기다리기 위한 대기 장소)를 이용하여 CPU 액세스를 통제한다. | ||
- 스케줄러는 인터럽트에 응답하고 CPU 코어 액세스를 관리한다. | ||
|
||
--- | ||
|
||
### 컨텍스트 교환 | ||
|
||
- 컨텍스트 스위치는 OS 스케줄러가 현재 실행중인 스레드/태스크를 없애고 대기중인 다른 스레드/태스크로 대체하는 프로세스이다. | ||
- 유저 스레드 사이에 발생하든, 유저 모드에서 커널 모드로 바뀌면서 일어나든 컨텍스트 교환은 비싼 작업이다. | ||
- 유저 스레드가 preemption 도중 커널 모드로 바꾸어 어떤 기능을 실행해야 할 때 모드가 바뀌면서 다른 캐시를 어쩔 수 없이 강제로 비워야 할 때가 있기에 캐시를 시스템 콜 반환 시 다시 채워야 하여 성능 저하로 이어진다. | ||
- 컨텍스트 교환은 CPU 낭비를 초래한다. | ||
- 리눅스는 가상 동적 공유 객체를 제공하여 이 현상을 방지한다. | ||
|
||
--- | ||
|
||
# 기본 탐지 전략 | ||
|
||
> 애플리케이션이 잘 돌아간다는 것은 CPU 사용량, 메모리, 네트워크, I/O 대역폭 등 시스템 리소스를 효율적으로 잘 이용하고 있다는 뜻이다. 성능 진단의 첫 단추는 어느 리소스가 한계에 다다랐는지 밝히는 일이다. | ||
### CPU 사용률 | ||
|
||
- 애플리케이션 성능을 나타내는 핵심 지표이다. | ||
- 유닉스 계열 OS 명령줄에 vmstat, iostate 명령어를 통해 가상 메모리 및 I/O 서브시스템 상태에 관한 유용한 데이터를 신속히 제공해야 한다. | ||
|
||
`vmstat 1`: 1초마다 한 번씩 찍어 다음 줄에 결과를 표시한다. 섹션별로 보면 다음과 같다. | ||
|
||
--- | ||
|
||
 | ||
|
||
- procs 섹션: 실행 가능한(r), 블로킹된(b) 프로세스 개수 | ||
- memory 섹션: 스왑 메모리, 미사용 메모리, 버퍼로 사용 가능한 메모리, 캐시로 사용 가능한 메모리 | ||
- swap 섹션: 디스크로 교체되어 들어간 스왑-인 메모리, 디스크에서 교체되어 빠져나온 스왑-아웃 메모리 | ||
- io 섹션: 블록-인, 블록-아웃 개수는 각각 블록 장치에서 받은 512바이트 블록, 블록 장치로 보낸 512 바이트 블록 개수이다. | ||
- system 섹션: 인터럽트 및 초당 컨텍스트 교환 횟수 | ||
- cpu 섹션: cpu와 직접 연관된 지표를 %로 표기한다. | ||
|
||
--- | ||
|
||
### Garbage Collection | ||
|
||
- 가비지 수집을 하려고 커널 교환을 할 일이 거의 없다. | ||
- 따라서 GC 자체는 유저 공간의 CPU 사이클을 소비하되 커널 공간의 사용률에는 영향을 미치지 않는 활동이다. | ||
- 반면 JVM 프로세스가 유저 공간에서 CPU를 100% 가까이 사용하고 있다면 GC를 의심해야 한다. | ||
- GC 로깅은 분석용 데이터의 원천으로서 가치가 높기에 JVM 프로세스는 GC 로그를 꼭 남겨야 한다. | ||
|
||
--- | ||
|
||
### 입출력 | ||
|
||
- 자바 프로그램은 대부분 단순한 I/O만 처리하기에 I/O 서브시스템을 심하게 가동시키는 애플리케이션 클래스는 적다. | ||
- 보통 I/O를 많이 쓰는 프로세스를 활발하게 모니터링하는 문화가 장착되어 있다. | ||
|
||
### 기계 공감 | ||
|
||
- 기계 공감은 성능을 쥐어짜내는 상황에서 하드웨어를 폭넓게 이해하고 공감할 수 있는 능력이 무엇보다 중요하다는 생각이다. | ||
- 고성능, 저지연이 필수인 분야에서 개발자가 자바/JVM을 효과적으로 활용하려면 JVM이 무엇이고, 하드웨어와는 어떻게 상호작용하는지 이해해야 한다. | ||
- 만약 두 스레드가 동일한 캐시 라인을 수저애서 성능 저하가 발생하면 이런 일이 발생할 수 있음을 이해하고 해결 방법을 찾아야 한다. | ||
|
||
--- | ||
|
||
> `가상화`는 다양한 종류가 있지만 보통 이미 실행중인 다른 OS 위에 OS 사본을 하나의 프로세스로 실행시키는 모양이다. | ||
>  | ||
--- | ||
|
||
# JVM과 운영체제 | ||
|
||
- JVM은 자바 코드에 공용 인터페이스를 제공하여 OS에 독립적인 실행 환경을 제공한다. 다만, 스레드 스케줄링같은 기본적인 서비스조차 하부 OS에 반드시 액세스해야 한다. | ||
- 이런 기능은 native 키워드를 붙인 네이티브 메서드로 구현한다. 이 작업을 대행하는 공통 인터페이스를 자바 네이티브 인터페이스(JNI)라 한다. | ||
- java.lang.Object 클래스에는 다음과 같이 non-private 네이티브 메서드가 선언되어 있다. | ||
|
||
```java | ||
public final native Class<?> getClass(); | ||
public final native void notify(); | ||
``` |