과거에는 윈도우용 프로그램과 리눅스용 프로그램, 맥용 프로그램을 전부 따로 만들어야 했다. 그래서 자바는 엄청난 선언을 한다
Write Once, Run Anywhere
클래스 로더(Class Loader)
프로그램이 실행되면 가장 먼저 하드디스크에 있는 바이트코드를 싹 모아서 메모리에 올린다.
실행 엔진(Execution Engine)
메모리에 올라온 바이트 코드를 기계어로 번역하고 실행한다. 이때 자주 쓰이는 코드는 매번 번역하지 않고 아예 기계어로 바꿔버리는 JIT(Just-In-Time)컴파일러를 사용하여 파이썬 보다 훨씬 빠른 계산 속도를 낸다.
메모리
스프링 부트로 서버를 띄우면 기본적으로 내장된 톰캣이라는 매니저가 프로그램 문을 연다.
미리 쓰레드를 생성해둔다.(200개의 Thread Pool)
1. 손님 입장 (요청 도착): 손님이 10명 들어옵니다.
2. 대기실에서 직원 호출: 톰캣 매니저가 쓰레드 풀(대기실)에서 쉬고 있던 직원 10명을 부릅니다.
3. 전담 마크 시작: 10명의 직원이 각각 1명의 손님을 맡아 주문을 처리합니다. DB 응답을 기다릴 때는 다른 일은 하지 않고 얌전히 기다립니다(Blocking).
4. 대기실 복귀 (반납): 식사(응답 완료)가 끝나면, 이 직원은 퇴사(쓰레드 소멸)하는 것이 아니라 다시 대기실(Pool)로 돌아가 다음 손님을 기다립니다.
손님이 201명 왔는데요?
FastAPI라면 1명의 직원이 비동기로 201번째 주문도 순식간에 받아버렸겠지만, 톰캣은 원칙상 직원이 남아있지 못하면 주문을 받지 못한다.
이에 대비하여 톰캣은 웨이팅 줄(Queue, Accept Count)를 준비해둔다.
- 큐(Queue) 대기: 201번째 손님부터는 식당 문 앞의 대기열(Queue)에서 줄을 서서 기다립니다. (기본적으로 100명까지 줄을 설 수 있습니다.)
- 직원 순환: 안에 있던 200명 중 누군가 서빙을 마치고 대기실로 돌아오면, 매니저가 잽싸게 그 직원을 대기열 1번 손님에게 배정합니다.
- 진짜 대참사 (Connection Refused): 만약 줄 서는 공간마저 꽉 차버린 상태에서 새로운 손님이 오면? 톰캣은 **"죄송합니다. 오늘 영업 끝났습니다"**라며 에러를 뱉어냅니다(이것이 그 유명한 서버 다운, 503 Service Unavailable 등의 상태입니다).
그래서 만약 트래픽이 몰릴 것이 예상되면, 이 쓰레드 풀의 크기(Max Threads)를 200에서 400으로 늘리거나, 대기열의 크기를 튜닝하는 작업을 하게된다.
앞서 톰캣 서버는 쓰레드가 쉴 새 없이 요청을 전담해서 처리한다고 했다. 그럼 공용으로 쓰이는 Heap 메모리에는 이 전 요청을 처리할 때 사용했던 데이터 객체들이 산더미 처럼 쌓인다.
생성된 데이터의 98%는 잠깐 쓰이고 바로 버려진다. 끝까지 살아남은 놈은 극소수다
예를 들어 손님이 주문할 때 잠깐 쓴 '주문서 객체'는 요리가 나오면 바로 쓰레기가 된다. 반면 '메뉴판 객체'나 '식당 설정 정보'는 식당이 문을 닫을 때 까지 살아있어야 한다.
그래서 GC는 힙 메모리라는 거대한 식당을 아예 두 구역으로 쪼개버린다.
🚨"전원 멈춰! 청소 끝날 때까지 아무도 움직이지 마!"
Stop-The-World(STW)
대청소가 시작되는 순간 톰캣의 200개의 애플리케이션 쓰레드는 하던 일을 완전히 멈추고 얼음상태가 된다. STW가 0.1초 만에 끝나면 다행이지만, 만약 메모리가 너무 꼬여서 3~5초 동안 멈춘다면? 그 5초 동안은 어떤 손님도 주문을 낼 수 없고, 식당 밖에서 대기하던 손님들은 앱 화면이 멈춰버리는 끔찍한 경험을 하게 된다. (API 지연 시간 폭발)
따라서 어떻게 하면 객체를 덜 만들어서 이 대청소를 최대한 안 일어나게 할까라는 고민에서 나온 것이 JVM 튜닝이다.
1) Heap Size 조절: 가장 기본적이고 직관적인 튜닝. 즉 청소할 공간의 절대적인 크기를 정해준다.
2) 구역의 비율 조절(Young vs Old 영역 크기)
3) 청소 업체 알고리즘(GC 알고리즘)
옛날에는 식당 크기나 비율을 수동으로 깎는 튜닝을 많이 했지만, 요즘 현대 자바(Java 8 이후 ~ Java 21)에서는 "그냥 더 똑똑하고 비싼 청소 업체를 고용하자!"로 트렌드가 바뀌었습니다.
서버를 띄울 때 어떤 청소 업체를 부를지 옵션으로 정해줄 수 있다.