728x90
반응형

요약 한 줄
스프링 MVC는 DispatcherServlet이 중앙에서 요청을 받아 HandlerMapping → HandlerAdapter → (Controller) → ViewResolver → View 순으로 흐름을 조율하고, 중간에 필터/인터셉터/예외처리/리졸버들이 참여하는 파이프라인입니다.

목차

  1. 전체 흐름(빅픽처)
  2. 주요 컴포넌트 한 줄 정의
  3. 요청~응답 단계별 상세
  4. 인터셉터 vs 필터 vs AOP
  5. 예외 처리 흐름(@ExceptionHandler, @ControllerAdvice, HandlerExceptionResolver)
  6. 확장 포인트(커스터마이징 체크리스트)
  7. 실전 코드 스니펫 모음
  8. 면접/시험 포인트 & 체크리스트

1) 전체 흐름(빅픽처)

HTTP 요청
  ↓ (Servlet Filter 체인)
DispatcherServlet
  ↓ HandlerMapping(매핑 찾기)
HandlerExecutionChain(핸들러 + 인터셉터들)
  ↓ HandlerAdapter(호출 어댑터)
@Controller/@RestController 메서드 실행
  ↓ (Model/ModelAndView or @ResponseBody)
ViewResolver(뷰 선택) ─ 또는 HttpMessageConverter(바디 변환)
  ↓ View 렌더링(템플릿/정적리소스) or JSON 직렬화
HTTP 응답

  

2) 주요 컴포넌트 한 줄 정의

  • DispatcherServlet: 프론트 컨트롤러. 요청/응답의 트래픽 경찰.
  • HandlerMapping: 어떤 컨트롤러 메서드가 이 URL/HTTP 메서드를 처리하는지 탐색.
  • HandlerAdapter: 찾아낸 핸들러를 실행 가능한 형태로 호출.
  • HandlerMethodArgumentResolver: 컨트롤러 파라미터(@RequestParam, @PathVariable, @RequestBody, 커스텀 타입 등) 주입.
  • HttpMessageConverter: HTTP 바디 ↔ 객체(JSON, XML 등) 직렬화/역직렬화.
  • ViewResolver: 뷰 이름을 템플릿(View)으로 해석(Thymeleaf, JSP 등).
  • HandlerExceptionResolver: 예외를 적절한 응답/뷰로 변환.
  • HandlerInterceptor: 컨트롤러 전/후/완료 시점 가로채기(로깅, 인증 등).

3) 요청~응답 단계별 상세

  1. 필터 체인
    • 서블릿 컨테이너 레벨. 인코딩 처리, 보안(스프링 시큐리티), 공통 로깅 등.
  2. DispatcherServlet 진입
    • doDispatch()에서 실질 처리 시작.
    • HandlerMapping으로 HandlerExecutionChain(핸들러 + 인터셉터 목록) 획득.
  3. 인터셉터(preHandle)
    • 인증/인가, 트랜잭션 컨텍스트, 트레이싱 ID 부여 등.
  4. HandlerAdapter → 컨트롤러 실행
    • 메서드 파라미터는 ArgumentResolver들이 채워줌.
    • 바디(JSON 등)는 HttpMessageConverter로 역직렬화.
  5. 핸들러 반환값 처리
    • 템플릿 렌더: ModelAndView → ViewResolver로 뷰 탐색 후 렌더.
    • REST 응답: @ResponseBody/ResponseEntity → HttpMessageConverter로 JSON 직렬화.
  6. 인터셉터(postHandle, afterCompletion)
    • 모델 가공, 뷰 렌더 이후 리소스 정리, 예외 로깅 등.
  7. 예외 발생 시
    • @ExceptionHandler(로컬) → @ControllerAdvice(글로벌) → HandlerExceptionResolver 순으로 처리.

4) 인터셉터 vs 필터 vs AOP

구분                                    적용 레벨                          주요 시점                                                       사용 예

Filter 서블릿 컨테이너 DispatcherServlet 전/후 인코딩, 보안, CORS, 공통 로깅
Interceptor 스프링 MVC 컨트롤러 전/후/완료 로그인 체크, 요청 컨텍스트, 성능 측정
AOP 스프링 빈 메서드 메서드 호출 단위 트랜잭션, 캐시, 로깅 단면화
 

인증/인가는 필터/시큐리티, 컨트롤러 전후 로직은 인터셉터, 서비스/리포지토리横단 관심사는 AOP가 깔끔합니다.

5) 예외 처리 흐름

우선순위: 로컬 @ExceptionHandler → 글로벌 @ControllerAdvice → HandlerExceptionResolver

  • REST라면 적절한 상태코드 + JSON 바디로 통일.
  • HTML 뷰 프로젝트면 공통 오류 페이지로 렌더.

6) 확장 포인트 체크리스트

  • WebMvcConfigurer로 인터셉터/리졸버/메시지컨버터 추가
  • HandlerMethodArgumentResolver로 커스텀 파라미터 주입(예: @CurrentUser)
  • MessageConverter로 Protobuf/CSV 등 포맷 지원
  • LocaleResolver/TimeZone로 지역화
  • ContentNegotiation으로 ?format=json/Accept 헤더 대응
  • ViewResolver 우선순위 조정(Thymeleaf, JSP, JSON 등)
  • ExceptionResolver 또는 @ControllerAdvice로 에러 표준화
  • 정적 리소스 캐싱과 ResourceHandler 튜닝

7) 실전 코드 스니펫

7-1. 간단 컨트롤러

@RestController
@RequestMapping("/api")
public class HelloController {
  @GetMapping("/hello")
  public Map<String, Object> hello(@RequestParam String name) {
    return Map.of("message", "Hello " + name);
  }
}

7-2. 인터셉터 등록

@Component
public class LogInterceptor implements HandlerInterceptor {
  @Override
  public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
    req.setAttribute("startAt", System.currentTimeMillis());
    return true;
  }
  @Override
  public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
    long took = System.currentTimeMillis() - (long) req.getAttribute("startAt");
    System.out.println("[TIME] " + req.getRequestURI() + " -> " + took + "ms");
  }
}

@Configuration
public class WebConfig implements WebMvcConfigurer {
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LogInterceptor()).addPathPatterns("/api/**");
  }
}

7-3. 커스텀 ArgumentResolver (예: @CurrentUser)

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {}

@Component
public class CurrentUserResolver implements HandlerMethodArgumentResolver {
  @Override public boolean supportsParameter(MethodParameter parameter) {
    return parameter.hasParameterAnnotation(CurrentUser.class);
  }
  @Override public Object resolveArgument(MethodParameter p, ModelAndViewContainer mav,
      NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
    return webRequest.getNativeRequest(HttpServletRequest.class).getAttribute("user");
  }
}

@Configuration
class MvcConfig implements WebMvcConfigurer {
  @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    resolvers.add(new CurrentUserResolver());
  }
}

7-4. 글로벌 예외 처리

@ControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(IllegalArgumentException.class)
  public ResponseEntity<Map<String, Object>> handleBadRequest(IllegalArgumentException e) {
    return ResponseEntity.badRequest().body(Map.of(
      "error", "BAD_REQUEST",
      "message", e.getMessage()
    ));
  }
}

7-5. 메시지 컨버터 추가(예: CSV)

@Configuration
public class HttpMsgConfig implements WebMvcConfigurer {
  @Override
  public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(0, new CsvHttpMessageConverter()); // 우선 등록
  }
}

8) 면접/시험 포인트 & 체크리스트

  • DispatcherServlet이 하는 일 3줄로 설명할 수 있는가?
  • HandlerMapping/Adapter/ExceptionResolver/MessageConverter 역할 구분 가능한가?
  • 인터셉터 vs 필터 vs AOP 적용 위치를 사례로 설명할 수 있는가?
  • REST에서 Content NegotiationHttpMessageConverter의 연결을 아는가?
  • 예외를 일관된 응답 스키마로 표준화하는가?
728x90
728x90
반응형

📚 목차

  1. 이게 왜 중요한데?
  2. 표 하나로 비교 끝!
  3. 언제 뭘 써야 하나요?
  4. 마무리 요약 (진짜 1분 컷)

1. 이게 왜 중요한데?

자바 개발하면서 List, Set, Map 구분 못 하면...
👉 NullPointerException, IndexOutOfBoundsException, 동기화 오류
줄줄이 터집니다.
그럼 PM이 와서 말하죠:

“그거... 그냥 ArrayList 말고 HashSet 쓰면 안 되나?”


2. 표 하나로 비교 끝! ✅

구분ListSetMap
중복 허용 ✅ O ❌ X ✅ Value만 O
순서 유지 ✅ O ❌ X (HashSet), ✅ TreeSet은 정렬됨 ❌ X (정렬 불가)
인덱스로 접근 ✅ O (get(index)) ❌ X ❌ X
Key-Value 구조 ❌ X ❌ X ✅ O
대표 클래스 ArrayList, LinkedList HashSet, TreeSet HashMap, TreeMap
 

3. 언제 뭘 써야 하나요?

상황추천 컬렉션
데이터 순서 유지 + 중복 허용 ArrayList
중복 없이 빠르게 저장 HashSet
정렬된 데이터 필요 TreeSet, TreeMap
Key로 조회 필요 HashMap
삽입/삭제가 많음 LinkedList
 

4. 마무리 요약 (1분 컷 핵심)

List<String> list = new ArrayList<>(); // 순서 O, 중복 O
Set<String> set = new HashSet<>();     // 순서 X, 중복 X
Map<String, String> map = new HashMap<>(); // Key-Value

📌 기억법:

  • List: 줄세우기 좋아함
  • Set: 중복 싫어함
  • Map: Key로 놀고 Value로 살고
728x90
728x90
반응형

Java에서 하나의 공통 자원을 공유하려 할 때 static 키워드와 Singleton 패턴은 자주 비교됩니다.
두 방식은 비슷해 보이지만, 메모리 처리, 객체화 여부, 유지보수성에서 큰 차이가 있습니다.

이 글에서는 두 개념의 본질적인 차이언제 어떤 방식이 적합한지를 명확히 정리해드립니다.


✅ static이란?

  • 클래스 로딩 시 Method Area에 한번만 할당
  • 객체 생성 없이 클래스명으로 직접 접근 가능
  • 공통 유틸리티나 상수 정의에 적합
public class Util {
    public static int add(int a, int b) {
        return a + b;
    }
}
Util.add(3, 5);  // 객체 없이 바로 사용

✅ Singleton이란?

Singleton 구현 방식은 내 블로그 - Java Singleton 패턴 설명 포스트를 참고해주세요.

  • 객체를 하나만 생성하도록 보장하는 디자인 패턴
  • 지연 생성(Lazy Initialization) 가능
  • 상태를 유지할 수 있으며, 다형성 사용 가능

🧠 static vs Singleton 비교

항목staticSingleton
생성 시점 클래스 로딩 시 필요할 때 (Lazy 가능)
메모리 위치 Method Area Heap
객체화 여부 ❌ (객체 없음) ✅ (객체 존재)
상태 관리 불가능 (stateless) 가능 (stateful)
테스트 용이성 어렵다 (전역처럼 작동) 비교적 쉬움 (Mock 객체 가능)
다형성 불가능 가능 (인터페이스 구현 등)
 

✅ 언제 static을 쓰고 언제 Singleton을 써야 할까?

🔹 static이 적합한 경우

  • 상태가 필요 없는 순수 유틸성 로직
  • 계산기능, 공통 상수, 로그 포맷 등

🔹 Singleton이 적합한 경우

  • 상태 저장이 필요한 공용 객체
  • 의존성 주입이 필요한 서비스, DB 연결 등

🎯 결론

  • static: 단순하고 빠르지만 유연하지 않음
  • Singleton: 설계는 복잡하지만 유연성과 확장성이 좋음

상황에 맞는 선택이 유지보수성과 테스트 효율성을 크게 좌우합니다.

728x90
728x90
반응형

JVM은 자바(Java)의 핵심이라 해도 과언이 아닙니다.
우리가 작성한 자바 코드가 어떻게 실행되는지,
플랫폼 독립성이 어떻게 보장되는지,
모든 답은 JVM에 있습니다.

이 글에서는 JVM이 무엇인지, 내부 구성 요소는 무엇이며,
왜 Java가 JVM 덕분에 강력한 언어인지 쉽게 정리해드립니다.

☕ JVM이란?

JVM (Java Virtual Machine) = 자바 가상 머신

자바 프로그램을 실행하는 엔진이자,
"한 번 작성하면 어디서나 실행된다 (Write Once, Run Anywhere)"라는 자바 철학을 실현해주는 핵심 기술입니다.


🔧 무슨 일을 할까?

JVM의 핵심 역할은 딱 하나:

컴파일된 .class 바이트코드 파일을 실행하는 것

즉, 우리가 작성한 .java 소스 코드는 **JDK의 컴파일러(javac)**에 의해 .class라는 바이트코드로 바뀌고,
이 바이트코드를 운영체제에 맞게 해석해서 실행하는 주체가 바로 JVM입니다.


🔍 JVM 내부 동작 구조 요약

[.class 파일]
      ↓
 Class Loader → 메모리에 로딩
      ↓
 Bytecode Verifier → 유효성 검사
      ↓
 Execution Engine → 실행 (JIT 컴파일 포함)
      ↓
 Native Code → 실제 OS에서 동작

📦 구성 요소 간단 설명

구성 요소역할
Class Loader 클래스 파일 메모리에 로드
Execution Engine 바이트코드 해석 & 실행
JIT Compiler 바이트코드를 네이티브 코드로 동적 변환
GC (Garbage Collector) 불필요한 객체 메모리 자동 정리
Runtime Data Area 메모리 공간 (Heap, Stack 등)
 

🤔 JVM이 왜 중요한가요?

  • 플랫폼 독립성: 같은 자바 프로그램이 Windows, Linux, macOS에서 실행 가능
  • 메모리 관리 자동화: GC 덕분에 개발자가 직접 메모리 해제할 필요 없음
  • 보안성: 바이트코드 검사 및 제한된 실행 환경 제공

📌 용어 간 관계 정리

용어설명
JDK 자바 개발 도구 세트 (JRE + 컴파일러 포함)
JRE 실행 환경 (JVM + 라이브러리)
JVM 실제 실행기 (JRE 내부에 있음)

 

728x90
728x90
반응형

✅ 한눈에 보는 차이표

구성 요소설명포함 관계주요 역할
JDK (Java Development Kit) 자바 개발 도구 전체 세트 JDK ⊃ JRE ⊃ JVM 개발 + 실행
JRE (Java Runtime Environment) 자바 실행 환경 JRE ⊃ JVM 실행만 가능
JVM (Java Virtual Machine) 자바 가상 머신 (실행 엔진) JRE ⊃ JVM 바이트코드 실행
 

🔍 1. JVM (Java Virtual Machine)

“Write once, run anywhere”를 실현시키는 핵심”

  • 역할: .class 파일(바이트코드)을 실행
  • 동작:
    1. Class Loader: 클래스를 메모리에 로딩
    2. Bytecode Verifier: 코드 검증
    3. Execution Engine: 코드 실행 (JIT 컴파일 포함)
  • OS/환경별로 다름: 각 OS에 맞는 JVM이 존재

🔸 JVM만으로는 자바 코드 작성 불가


🔍 2. JRE (Java Runtime Environment)

“자바 프로그램을 실행할 수 있는 환경”

  • 구성:
    • JVM
    • 자바 클래스 라이브러리(rt.jar)
    • 필요한 기타 실행파일 (예: java 명령어)
  • 목적: 자바 프로그램 실행만 가능 (컴파일 ×)
  • 대상: 자바 개발이 아닌 실행만 필요한 사용자 (예: 서버 운영자)

🔸 개발 도구 없음 (javac X)


🔍 3. JDK (Java Development Kit)

“자바를 개발하기 위한 모든 도구 포함”

  • 구성:
    • JRE
    • 개발 툴 (javac, javadoc, jar 등)
  • 역할: 자바 소스 코드를 작성, 컴파일, 디버깅 가능
  • 대상: 자바 개발자

🔸 JDK 설치하면 JRE, JVM 포함

[JDK]
 └── [JRE]
       └── [JVM]

🧠 쉽게 외우는 포인트

외우는 방법
JVM은 바이트코드를 실행하는 엔진
JRE는 JVM + 실행 라이브러리 = 실행 환경
JDK는 JRE + 개발 도구 = 개발 키트
 

🎯 개발자 입장에서 요약

  • 자바 코드 작성 ➡️ JDK 필수
  • 자바 앱 실행만 ➡️ JRE만 설치해도 가능
  • 바이트코드 실행 책임자 ➡️ JVM

 

728x90
728x90
반응형

오늘은 백엔드 개발할 때 "어떤 자바 버전 쓰면 좋을까?"에 대한 내용을 쉽게 정리해봤어요.

요즘도 Java 8 쓰는 데가 있다는데… 진짜일까요? 최신 버전은 어떤 걸까요?


✅ 자바 버전, 한눈에 요약!

순위자바 버전특징 & 상황
1위 Java 11 (LTS) 대기업, 공공기관, SI의 국민템! 안정성과 호환성 짱.
2위 Java 8 (LTS) 아직도 많이 쓴다! 레거시 프로젝트에 필수.
3위 Java 17 (LTS) 요즘 Spring Boot 3.0+는 거의 이걸 씀. 모던 개발 스타일
4위 Java 21 (최신 LTS) 새로운 프로젝트라면 이게 최고! Loom(가상 스레드) 기대주.
 

🥇 Java 11 – 지금도 가장 널리 쓰이는 LTS

  • 출시: 2018년
  • 특징:
    • 안정성 최고
    • Java 8보다 진보된 기능 탑재
    • 기업이 제일 많이 채택 중
  • 💡 나도 Spring Boot 2.7 개발할 땐 이거 썼어요.

🥈 Java 8 – 고인물이지만 무시 못함

  • 출시: 2014년
  • 특징:
    • 스트림, 람다식 도입으로 한 획 그었죠
    • 하지만 이제는 조금씩 퇴장 중
    • 아직 공공기관이나 SI에서 자주 나옴

🥉 Java 17 – 스프링 부트 3.0의 짝꿍

  • 출시: 2021년
  • 특징:
    • Records, Sealed class 같은 최신 문법 가능
    • Spring Boot 3.0부터 이걸 기본으로 삼아요
    • JDK 8~11 벗어나고 싶다면 이게 무난함

🌟 Java 21 – 최신이자 미래형 자바

  • 출시: 2023년
  • 특징:
    • Virtual Threads (비동기 개발에 짱)
    • Unnamed classes, String templates
    • JDK 업데이트 정책이 빠르게 도는 요즘, Java 21은 미래 대비로 GOOD
  • ⚠ 단점: 일부 라이브러리 호환성은 확인 필요

🚫 Java 22 이상은요?

  • LTS(장기지원)가 아님
  • 테스트, 실험용으로는 좋지만 기업은 아직 관심 없음

✍️ 결론 – 어떤 버전을 써야 할까?

👉 신규 프로젝트: Java 17 또는 Java 21
👉 레거시/기관 시스템 유지보수: Java 8 또는 Java 11
👉 Spring Boot 3.x 사용: Java 17 이상 필수!


🔧 개인적인 팁!

  • 저는 요즘 모든 프로젝트를 Java 21 + Spring Boot 3.2로 짭니다.
  • 이유? 미래 대비 + 테스트 성능 + Swagger 호환성까지 굿!

📌 마무리 요약

🔹 Java 11은 국민 표준
🔹 Java 17/21은 미래 지향적 선택
🔹 Java 8은 아직도 현실에서 존재함
🔹 최신 Spring Boot는 17 이상 필수!


👉 도움이 되셨다면 공감 + 댓글 부탁드려요 😊

 

 

728x90
728x90
반응형

1. 스프링의 시작은 책 한 권에서

스프링(Spring)은 단순한 프레임워크 그 이상입니다. 그 시작은 2002년, Rod Johnson이 집필한 『Expert One-on-One J2EE Design and Development』라는 책에서 등장한 소스 코드에서 비롯됩니다. 당시 **EJB(Enterprise JavaBean)**는 무거운 구조와 복잡성으로 인해 '겨울'과도 같았죠. Rod는 이를 비판하며 '단순함'을 추구했고, 그 철학이 '봄(Spring)'이라는 이름으로 이어진 것입니다.

❝ EJB의 겨울을 지나, 스프링의 봄이 온다 ❞

스프링은 2003년 6월에 처음 세상에 공개되었고, 오픈소스 프로젝트로서 Apache License 2.0을 따릅니다. 2022년 11월 기준으로는 6.0.0 버전까지 출시되어 있으며, 주요 기능은 이제 Spring Boot를 중심으로 구현되고 있습니다.

2. 왜 스프링이 중요한가?

  • POJO 기반: 복잡한 컴포넌트 없이 순수한 Java 객체로 개발이 가능.
  • DI/IoC 컨테이너: 객체의 생성과 의존성 관리를 프레임워크가 자동으로 처리.
  • 모듈화: AOP(Aspect-Oriented Programming)를 통해 핵심 로직과 부가 기능을 깔끔히 분리.
  • JVM 기반 호환성: Java는 물론 Kotlin 등 다양한 언어와도 호환.
  • 강력한 생태계: Spring MVC, Spring Data, Spring Security, Spring Cloud 등 수많은 확장 가능성.
  • 전자정부 프레임워크 기반: 국내 공공기관 시스템의 표준으로도 사용.

3. 스프링을 제대로 활용하려면?

  • Spring Boot로 시작하면 빠르고 간단한 설정이 가능
  • IntelliJ IDEA는 Spring에 최적화된 대표 IDE (JetBrains 공식 지원)
  • 테스트/배포 자동화까지 생각한다면 Swagger, Docker, GitHub Actions와 연동 추천

✍️ 요약문

스프링은 복잡했던 Java EE의 시대에 ‘단순함’이라는 가치를 제시하며 등장한 웹 프레임워크입니다. Rod Johnson의 철학에서 출발한 이 프로젝트는 이제 전 세계 수많은 기업과 공공기관이 사용하는 강력한 인프라가 되었습니다. 만약 Java 기반 백엔드를 시작하고 싶다면, Spring은 그 자체로도 가장 강력한 출발점입니다.

728x90
728x90
반응형

자바 개발자라면 꼭 알고 있어야 하는 GC(Garbage Collector)!
객체는 언제 메모리에서 사라지고, 애플리케이션이 왜 가끔씩 멈추는지 궁금하셨나요?
아래 이미지와 함께 GC의 작동 구조를 쉽게 설명해드립니다.


🔍 GC 개념 요약

**Garbage Collector(GC)**는 사용하지 않는 객체를 힙 메모리에서 자동으로 제거하는 JVM의 기능입니다.
메모리 누수를 방지하고 개발자가 직접 메모리를 관리하지 않아도 되게 해주는 아주 고마운 기능이죠.


🧠 Java 힙 메모리 구조

아래 이미지는 자바 힙(Heap) 메모리의 구성과 객체 이동 과정을 시각적으로 표현한 구조입니다.

✅ 설명:

  • 객체는 먼저 Eden 영역에 생성됩니다.
  • GC(Minor GC)가 발생하면 Eden → Survivor1 → Survivor2를 오가며 살아남습니다.
  • 여러 번 살아남으면 Old 영역으로 이동합니다.
  • Old가 꽉 차면 **Major GC (또는 Full GC)**가 발생합니다.
  • Permanent(또는 Java 8 이후 MetaSpace)는 클래스 정보 등 JVM 메타데이터를 저장하는 공간입니다.

💥 GC의 종류

GC 종류대상 영역특징
🧹 Minor GC Young Generation (Eden + Survivor) 빠르고 자주 발생함
🧹 Major GC Old Generation 느리고 멈춤(STW)이 발생함
🧹 Full GC 전체 힙 영역 Major GC 포함 + 기타 리소스 정리
 

🛑 STW(Stop The World)란?

GC를 수행하는 동안 JVM의 모든 스레드가 멈추는 현상입니다.
특히 Major GC나 Full GC 시 STW가 발생하며 사용자 체감 지연이 생길 수 있습니다.

📌 GC 튜닝의 핵심: STW 시간을 최소화하는 것!


⚙ 대표적인 GC 알고리즘

GC 종류특징적합 환경
Serial GC 단일 스레드, 기본 구조 저사양/테스트용
Parallel GC 멀티스레드 병렬 처리 일반 서버, 병렬 CPU
Parallel Old GC Old까지 병렬 처리 고사양 서버
G1 GC Region 단위 처리, STW 최소화 Java 9 이상 대규모 앱
ZGC/Shenandoah 실시간 GC, STW 거의 없음 실시간 처리 시스템
 

🧰 개발 팁 요약

  • 객체는 가능한 빨리 Eden에서 제거되도록 설계하자
  • Old로 가는 객체는 재사용하거나 Pool 처리가 바람직
  • GC 튜닝 시에는 G1 GC, ZGC 등 최신 GC 전략 고려

✅ 마무리

GC는 Java의 강력한 장점 중 하나지만,
그 내부 동작을 모르면 애플리케이션 지연이나 STW 문제를 겪기 쉽습니다.
이제 GC 동작 구조를 알았으니, 메모리 튜닝과 성능 최적화에 자신감이 붙으실 겁니다!

728x90

+ Recent posts