증상 발견
- Prometheus + Grafana를 조합하여 Spring Boot로 개발된 Batch 프로그램을 모니터링중
- LiveThreads가 증가하고 있다.
- DeamomThreads 일정 한 패턴으로 증가와 감소를 반복하고 있다.
원인파악
- Batch 코드를 확인해보니 성능을 올리기 위해 Threads 처리 부분에서 Threads리소스를 정리 하지 않음.
public void scheduler(){
ExecutorService executorService = Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
executorService.submit(() -> {
//실행로직
System.out.println("Threads 처리 중");
});
}
}
해결
해결1. 함수내에 Threads 리소스 정리 로직 추가
- exceutorService.shudown() 추가
public void scheduler(){
ExecutorService executorService = Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
executorService.submit(() -> {
//실행로직
System.out.println("Threads 처리 중");
});
}
//Threads 종료 로직
executorService.shutdown();
}
해결2. ExecutorService 전역변수로 선언.
- exceutorService.shudown() 추가
private ExecutorService executorService = Executors.newFixedThreadPool(3);
public void scheduler(){
for(int i=0;i<10;i++){
executorService.submit(() -> {
//실행로직
System.out.println("Threads 처리 중");
});
}
}
해결1 vs 해결2
함수내에 Threads 리소스 정리 로직 추가 | ExecutorService 전역변수로 선언 | |
장점 | - 작업이 완료되면 Thread가 반납되어 메모리를 지속적으로 점유하는것을 방지한다. | - 매번 Thread를 생성하고 종료하는 과정이 반복되어오버헤드를 유발할 수 있다. |
단점 | - 스레드 풀이 한 번 생성되고 애플리케이션이 종료될 때까지 유지되므로 반복적인 생성 및 종료 오버헤드를 방지할 수 있다. | - 전역 스레드 풀을 사용하면 해당 스레드 풀이 사용되지 않는 동안에도 메모리를 점유하고 있어 메모리 누수가 발생할 가능성이 있다 - 여러 메소드에서 공유할시 동기화 문제가 발생할 수 있다. |
'Error' 카테고리의 다른 글
[NextJS]Nextjs Ngingx 배포시 socket Error (1) | 2024.01.05 |
---|---|
[Error]DataAccessException (0) | 2022.08.07 |
[JVM]Run Time VS Compile Time (0) | 2022.06.10 |
[Error]Throwable (0) | 2022.05.20 |