팀원이 부하테스트 진행 중 요청 수를 100에서 1000으로 늘렸는데
100이 더 오래 걸렸다고 한다.
원인 후보는 여러 가지가 있겠지만,
나는 JVM 동작 과정이 먼저 생각났다.
다른 팀원은 Spring의 쓰레드 생성 과정 등 Spring에 대한 이해도 필요하다고 알려주었다.
(이것은 생각조차 못 했다.)
또한 쓰로틀링 등의 HW 실행 속도의 문제일 수도 있다.
프로세스 간의 hw 리소스에 대한 자원 경쟁도 고려해야 한다.
윈도우에서 서버 응답 시간이 수만배 이상 느려진 문제를 겪었던 경험도 있었기에
원인을 찾는 것은 쉽지 않을 것이라 예측된다.
HW부터, OS, 실행 프로세스, JVM, Spring, Apache JMeter까지 문제의 원인을 찾는 것은 험난 할 것으로 예상된다. 가장 가능성이 있는 JVM, Spring, Apache JMeter로 원인을 한정하고 문제의 원인을 찾아보고자 한다.
해당 포스트에서는 JVM의 일부 JIT 컴파일 이해를 다루어 보기로 했다.
JVM의 JIT 컴파일러가 실행 중에 바이트코드를 네이티브 코드로 변환하여 수행한다.
즉, 처음에는 인터프리터 방식으로 실행하지만
실행 중에 자주 실행하는 바이트코드를 최적화하여 네이티브 코드로 변환한다.
가상 머신의 인터프리터 방식에 비해
네이티브 코드로 실행하는 과정이 더 빠르다.
따라서 초기 실행 속도와 최적화된 코드 둘 중 어느 코드로 실행하는지에 따라 실행 속도가 다르다.
신중히 고려해야 예측 가능한 결과를 취할 수 있다.
아직 팀원들과 답을 찾고 있지만, 현재 생각중인 방안은 프로그램을 충분히 실행하여 네이티브 코드로 변환된 이후에 성능 테스트를 실행하는 것을 고려하고 있다.
Java는 한번 작성 후 어디서든 실행하는 것을 목표로 하였다.
C, C++ 언어는 실행하는 컴퓨터 시스템에 맞추어 컴파일해야 한다.
각 네이티브 코드는 다르기 때문에 컴파일된 코드는 다른 시스템에서 작동하지 않을 수 있다.
이에 자바는 인터프리터 방식을 선택하였다.
바이트코드인 중간 코드로 변환하고, 이를 JVM이 설치되어 있으면 실행될 수 있도록 하였다.
하지만 인터프리터 방식은 한줄 씩 가상 머신이 해석하고 다시 네이티브로 실행하게 된다.
속도의 측면에서 이점이 낮다.
인터프리터 실행 속도에 대한 비효율로 인해 실행 중에 네이티브 코드로 변환한다.
자바는 이러한 이유로 느리게 시작하게 된다.
자바의 초기 실행 속도를 더 빨리 할 수 있도록 자바도 AOT 컴파일을 지원한다.
처음부터 네이티브로 실행하니 JIT 보다 성능이 좋다고 할 수 있을까?
그렇다고 단정하기는 어렵다.
JIT 컴파일은 단순히 실행 중에 네이티브로 컴파일하는 것이 아니다.
실행 통계를 반영하여 최적화한 후 동적 컴파일이 수행된다.
실행할수록 최적화가 점차 진행되어 실행 속도가 더 빨라질 수 있다.
최적화가 적용되지 않는 경우는 인터프리터 방식으로 실행된다.
JIT 컴파일은 느리게 시작한다.
여러번 재시작하는 CI/CD에서는 최적화가 되어도 최적화 전으로 돌아가기 쉽다.
그렇기 때문에 AOT 컴파일을 고려하는 것이 합리적일 수 있다.
안타깝게도 Garbage Collection역시 JVM 실행에 중요한 요소이다.
성능이 개선되고는 있지만 여전히 stop the world에 대해 고려해보아야 한다.
Garbage Collection은 성능 평가에서 고려해야 할 중요한 요소로 판단된다.
이것은 좀 더 알아보고 기회가 된다면 작성하기로 한다.
틀린 내용은 수정해주시면 감사하겠습니다 :D