Skip to content

Commit

Permalink
Merge pull request #3 from jivebreaddev/main
Browse files Browse the repository at this point in the history
1주차 pr입니다.
  • Loading branch information
jivebreaddev authored Jan 23, 2024
2 parents a00b8a8 + b0244e0 commit fe26de5
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 0 deletions.
69 changes: 69 additions & 0 deletions ch02/박시창.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 2. JVM 이야기
- 성능에 관심이 있는 개발자라면 기본적인 jvm 기술 스택을 이해해야합니다.
## 2.1 인터프리팅과 클래스로딩
- 자바 가상 머신을 규정한 명세서에 따르면 jvm은 스택 기반의 해석머신 (물리적 레지스터는 없지만 실행스택에 보관하여 계산합니다.)
- JVM의 인터프리터의 기본 로직은, 중간 값을 담아두고 가장 마지막에 실행된 명령어와 프로그램을 구성하는 옵코드를 하나씩 처리하는 'WHILE 루프안의 OPCODE'
- JAVA 실행시에는,
- 1. 가상 머신 프로세스(자바 바이너리)를 ㅅ구동
- 2. 자바 가상 환경 구성
- 3. 스택 머신이 초기화된 다음, HelloWorld 클래스 파일 실행
- 4. 진입점, Helloworld.class 에 있는 main() 메서드
- 5. 가상 머신 실행 전에 클래스를 로드한다.
- a. 부트스트랩 클래스 -> 자바 런타임 코어 클래스 로드 (최소한의 필수 클래스 로드: java.lang.Object, Class, Classloader)
- b. 확장 클래스로더 -> 부트스트랩 클래스로더를 부모로 설정하고 로딩(특정한 os 나 플랫폼 네이티브 코드)
- c. 애플리케이션 클래스로더 생성, 지정된 클래스패스에 유저클래스 로드
- d. 새 클래스는 디펜던시에 로드 (클래스로더에 룩업 넘김) -> 없으면 ClassNotFoundException
- e. 한 클래스는 풀클래스명, 자신을 로드한 클래스로드로 식별 (이중 로딩 방지)

## 2.2 바이트 코드 실행
- 자바 컴파일러 javc를 이용해 컴파일 하는것
- 1. javac 컴파일 -> 자바 소스코드를 바이트코드 형태 .class로 변경
- 2. javap( 역어셈블리툴)로 열어보면 자바 코드 어렵잖게 알아 볼 수 있ㅇ므
- 3. 바이트 코드는 특정 컴퓨터 아키텍쳐에 특정핮 ㅣ않은 중간 표현형(jvm지원 플랫폼 어디든 실행 가능하다.)
- 4. 클래스 해부도
- a. 매직넘버
- b. 클래스 파일 포맷 버전
- c. 상수 풀
- d. 액세스 플래그
- e. this 클래스
- f. 슈퍼클래스
- g. 인터페이스
- h. 필드
- i. 메서드
- j. 속성 (소스파일명)
-
## 2.3 핫스팟 입문
- c++는 제로 오버헤드 원칙입니다. -> 아주 세세한 저서준 까지 명시해야함
- 핫스팟은 런타임 동작을 분석하고 성능에 가장 유리한 방향으로 영리한 최적화를 적용하는 가상 머신입니다.

## 2.4 JIT 컴파일이란
- 자바 프로그램은 바이트코드 인터프리터가 가상화한 스택 머신에서 명령어를 실행하며 시작된다.
- 프로그램 단위(메서드와 루프)를 인터프리티드 바이트 코드에서 네이티브 코드로 컴파일 합니다. -> jit 컴파일이라고 부릅니다.
- 애플리케이션을 모니터링 하면서 가장 자주 실행하는 코드 파틀르 발견해서 jit 컴파일으로 수행합니다. 10장
- 특정 메서드가 어느 한계치를 넘어가면 프로파일러가 특정 코드 섹션을 컴파일/최적화 합니다.
- 컴파일러 해석 단계에서 수집한 추적정보를 근거로 최적화를 결정 합니다.
- 자바에서는 PGO(Profile guided Optimization)을 으용해서 런타임 정보를 동적 인라이닝, 가상호출로 성능을 개선할 수 있습니다. 9장
- 핫스팟 vm은 시동시 cpu 타입을 정확히 감지해서 특정 프로세서의 기능에 맞게 최적화 적용할 수 있습니다.
## 2.5 JVM 메모리 관리
- 자바는 가비지 수집이라는 프로세스를 이용해 힙 메모리를 자동 관리하는 방식 해결합니다.
- jvm이 더 많은 메모리를 할당 해야할 때 불필요한 메모리를 회수하거나 재사용하는 불확정적 프로세스 입니다.

## 2.6 스레딩과 자바 메모리 모델(JMM)
- JVM처럼 멀티스레드 기반인 깓락에 자바프로그램이 작동하는 방식은 복잡하고 분석하기 힘들어졌습니다.
- 하나의 전용 OS스레드에 정확히 하나의 자바 에플리케이션 스레드가 대응됩니다.
- JAVA 멀티스레드 방식은 세가지 원칙에 기반합니다
- 자바의 프로세스의 모든 스레드는 가비지가 수집되는 하나의 공용 힙을 가진다.
- 한 스레드가 생성한 객체는 그 객체를 참조하는 다른 스레드가 액세스 할 수 있다.
- 객체는 변경 가능하다. FINAL이 아닐시 바뀔 수 있다.
- 상호 배타적 락은 코드가 동시 실행되는중 객체가 손상되는 현상을 막을 수 있습니다. JMM의 원리와 스레드 락을 다루는 방법은 12장에서 다룹니다.
## 2.7 JVM 구현체 종류
- OPENJDK
- Oracle
## 2.8 JVM 모니터링과 툴링
- JMX (Java Management Extension)
- Java Agent
- jvm에 동작하는 애플리케이션을 제어하고 모니터링하는 강력한 범용 툴입니다.
## 2.8.1 VisualVm
- 자바 프로세스 모니터링툴


83 changes: 83 additions & 0 deletions ch03/박시창.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 3. 하드웨어와 운영체제

## 3.1 최신 하드웨어 소개
## 3.2 메모리
- 프로세서 코어의 데이터 수요를 메인 메모리가 맞추기 어려웠다.
- 클록 속도가 올라가도 cpu는 메모리가 도착할때까지 놀았다.
- cpu 캐시가 고안되서 L1, L2 가 사본을 떠서 보관한다.
- MESI에 따라 상태가 변경되며 무효화 브로드캐스팅을 합니다.
- 초기 프로세서는 매번 캐시 연산결과를 메모리에 기록 -> WRITE-THROUGH -> 메모리 대역폭을 너무 많이 소모, 효율 낮음
- 후기 프로세서는 WRITE-BACK을 채택해서 캐시 블록을 교체해도 DIRTY 캐시 블록만 메모리에 기록해서 메모리 기록의 비율이 낮습니다.
- 캐시 기술로 최대 전송률을 높일 수 있습니다.
- 메모리 클록 주파수
- 메모리 버스폭
- 인터페이스 개수

## 3.3 최신 프로세서의 특성
- 변환 색인 버퍼(TLB)
- 가상 메모리 주소를 물리 메모리 주소로 매핑하는 페이지 테이블의 캐시역할을 수행한다.
- 가상 주소를 참조해 물리주소 액세스가 쉽다.
- TLB가 없으면 L1캐시에 페이지 테이블이 있어도 16사이클이 걸린다
- 분기 예측과 추측 실행
- 분기 예측은 조건 분기에 대한 기준값 평가하느라 대기하는것을 미리 예상하고 실행후에 아니라면 파이프라인을 제거합니다.
- 보안문제가 있었ㅇ므 2018년
- 하드웨어 메모리 모델
- 서로 다른 CPU가 일관데게 동일한 메모리 주소를 액세스 할 수 있을까?
- 코드 실행순서를 바꿀수있다. -> 현재 스레드가 바라보는 결과에 아무런 영향이 없다는 전제가 잇다면
## 3.4 운영체제
- OS의 주 임무는 여러 실행 프로세스가 공유하는 리소스 액세스를 관장하는 일
- 메모리 관리 유닛(MMU)를 통한 가상 주소 방식과 페이지 테이블은 메모리 엑세스 제어의 핵심으로 한 프로세스가 소유한 메모리 영역을 다른 프로세스가 함부로 훼손 못함
- TLB는 물리 메모리 룩업시간을 줄임
- MMU는 굉장히 저수준이라서 OS 액세스 스케줄러를 살펴보자

## 3.5 스케줄러
- 프로세스 스케줄러는 CPU 액세스를 토제
- 실행 큐를 이용한다.
- OS 스케줄링은 10%, 20%의 오버헤드를 발생시킨다. WAIT, SLEEP 같은 I/O, 소프트웨어 인터럽트나 코어 액세스를 관리합니다.
- 타이밍은 성능 측정, 프로세스 스케줄링에 중요합니다.
## 3.6 컨텍스트 교환
- CONTEXT SWITCH는 OS 스케줄러가 현재 실행 중인 스레드/태스크를 없애고 대기 중인 다른 스레드/태스크로 대체하는 프로세스입니다.
- 유저모드 -> 커널모드 -> 컨텍스트 모드가 생기고 TLB, 다른 캐시까지 무효화가 됩니다.
- 이를 만회하려고 Vdso 같은 특권이 필요없는 유저 공간의 메모리 영역을 생성했습니다.

## 3.6 단순 시스템 모델
- 자바 애플리케이션의 구조
- 애플리케이션이 실행되는 하드웨어 os
- 애플리케이션이 실행되는 jvm, 컨테이너
- 애플리케이션 코드 자체
- 애플리케이션 호출하는 외부 시스템
- 애플리케이션에 유입되는 트래픽

### 3.6.1 cpu 사용률
- cpu 사용률은 애플리케이션 성능을 나타낸는 핵심 지표입니다.
- 부하중에 가능한한 100%에 가까워야합니다.
- vmstat으로
- proc -> r, b 프로세스 갯수
- memory -> swap 메모리, 비사용 메모리, 버퍼로 사용한 메모리, 캐시로 사용한 메모리
- swap -> 디스크가 교체되어 들어간 메모리, 디스크가 교체되어 빠져나온 메모리
- system 섹션 -> 인터럽트 및 초당 컨텍스트 교환 횟수입니다.
- cpu 섹션: 유저시간, 커널시간, 유휴시간, 대기시간, 도둑맞은 시간 표기합니다.
- CPU 사용률이 100%을 치지않으면 왜 그럴까를 따져야합니다
- 락때문에 발생한 컨텍스트 교환인가?
- IO경합이 일어나 블로킹이 발생햇나?
- VMSTAT에서 컨텍스트 교환 비율이 높게 나타나면 IO에서 블로킹이 일어났거나, 스레드 락 경합 상황이 벌어졌을 공산이 큽니다.
### 3.6.2 가비지 수집
- 핫스팟 JVM은 시작시 메모리를 유저 공간에 할당합니다.
- JVM 프로세스가 유저공간에서 CPU를 100%을 치면 GC를 의심해야합니다.
- 커널에서는 GC하지않음
- JVM에서 유저공간의 CPU사용률이 높은건 거의 GC 서브시스템 탓입니다.
- GC로깅은 분석용 데이터의 원천으로 가치가 높아서 운영환경에서는 꼭 남겨야합니다.
### 3.6.3 입출력
- 파일 I/O는 예로부터 전체 시스템 성능에 암적인 존재였습니다.
- 메모리에는 가상 메모리라는 우아한 격리 장치가 있지만, I/O는 개발자가 추상화할 장칙 ㅏ없습니다.
- IOSTAT으로 기본카운터를 진단하기에 더할 나위 없이 좋습니다.
### 커널 바이패스 I/O
- 커널을 이용해 데이터를 복사해 유저공간에 넣는 작업이 상당히 비싼 고성능 애플리케이션이 있다.
- 이러한 경우 커널 대신 네트워크 카드에 직접 데이터를 매핑하는 전용 하드웨어/소프트웨어를 사용합니다.

### 가상화
- 가상화 오버헤드 작아야한다.
### 3.8
- 스레드 스케줄링 같은 서비스를 OS에 액세스 해야한다.
- 이런기능은 JNI라는 네이티브 메서드로 구현됩니다.

Loading

0 comments on commit fe26de5

Please sign in to comment.