가비지 컬렉션(GC) 해부: 자바 개발자가 꼭 알아야 할 메모리 관리의 모든 것

GC banner

자바 기반의 Spring Boot로 백엔드 개발을 하다 보면 어느 순간 애플리케이션이 느려지거나 식은땀 나게 만드는 OutOfMemoryError같은 에러를 한번씩은 봤을 것이다. 이 때 GC의 동작 원리를 정확히 알고 있다면 문제의 원인을 찾아 해결하는데 많은 도움이 된다. 이번 포스팅에서는 자바 애플리케이션을 개발하면서도 막연히 알고 있던 가비지 컬렉션(GC)에 대해서 정리해 보고자 한다.

java21 처리량 향상을 위한 대안 – virtual thread

java virtual thread banner

2023년 9월 21일에 java 21이 배포가 되었다. java 21에서 새롭게 소개된 항목 중 하나가 기존의 스레드보다 더 경량화되어 설계된 virtual thread (가상 스레드)라고 할 수 있겠다. 이번 포스팅에서 새롭게 소개된 virtual thread(이하 가상 스레드)에 대해서 정리해 보고자 한다.

자바 메모리 다이어트: 몇가지 자바 메모리 최적화 기법

자바 메모리 최적화 배너

자바 애플리케이션의 성능을 결정짓는 핵심은 효율적인 메모리 설계와 이를 뒷받침하는 검증 과정에 있다. 이번 포스팅에서는 문자열 최적화부터 가상스레드까지 메모리를 아끼는 5가지 기법을 소개하고자 한다.

인텔리제이(IntelliJ)로 K8s 파드(Pod) 실시간 Java Remote Debugging 방법

Remote Debugging 배너 이미지

쿠버네티스 환경의 서비스에 애플리케이션 배포를 하기 전에 QA 검증 과정을 거칠 것이다. 검증 과정 중에 발생한 이슈의 원인을 확인 하기 위해서 때로는 추가적인 로그를 코드에 추가해서 다시 테스트 환경에 애플리케이션에 배포 후에 로그 내용을 확인하는 매우 번거로운 과정을 반복하는 경우가 있다. 추가한 로그를 통해서도 명확히 원인 파악이 안된다면? 또 다시 의심되는 부분을 찾아서 로그를 추가하고 또 배포해서 확인하고… 시간적으로 그리고 일의 능률 측면에서 매우 비효율적이 아닐 수 없다. 이번 포스팅에서는 테스트 환경에서 이러한 비효율을 단번해 해결할 수 있는 Remote Debugging 을 적용하여 Pod 내의 애플리케이션을 로컬에서 디버깅 할 수 있는 방법을 소개하고자 한다. (ft. IntelliJ)

스레드 누수는 이제 그만! Structured Concurrency 소개 (ft. JDK 25)

Java 애플리케이션을 개발하다 보면 스레드 사용은 매우 중요한 요소다. 그동안 ExecutorService나 CompletableFuture를 사용하면서 기능적으로 하나의 트랜잭션 기능으로 묶인 여러 스레드 중에서 하나라도 예외가 발생하는 스레드가 있다면 나머지 스레드를 관리하기 위한 복잡한 에러 로직을 사용했을 것이다.(cancel() 호출..) 하지만 이번에 소개할 Structured Concurrency는 이러한 골치아픈 문제를 해결해 줄 것이다. 또한 JDK21 버전에서 정식 릴리즈된 가상 스레드에 맞춰 병렬로 실행 되는 여러 스레드에 대한 관리 측면에서도 많은 도움이 될 것 같다.

Invalid Keystore Format Error를 대하는 우리의 자세

Java 기반 시스템을 운영하다 보면 보안 설정을 위해서 인증서나 비밀 키를 저장하는 키스토어를 자주 다루게 된다.
특히 java.io.IOException: Invalid Keystore Format 예외는 어쩌면 가장 자주 마주치는 예외일 것이다.
이번 포스팅에서는 Baeldung의 최신 가이드를 바탕으로 이 에러의 원인을 파악하고 해결하는 실무 노하우에 대해서 정리하고자 한다.

이 에러는 keystore 파일 형식과 Java 코드에서 기대하는 형식(JKS, PKCS12등)이 일치하지 않거나 빌드 과정 또는 전송 중에 파일이 손상된 경우 발생하며 정확한 진단 도구와 설정을 통해 해결할 수 있다.

Java25 Compact Object Header로 HotSpot JVM에서 메모리 절약

지난 9월에 Java25 버전이 정식 릴리즈 됐다. 여러가지 개선과 변화가 있었지만 그 중 눈에 띄는 항목 중 하나가 있었다. 바로 Compact Object Header 기능으로 객체의 헤더 사이즈를 기존 12~16byte에서 8byte로 줄였다는 내용이다. 8byte 라는 수치가 상당히 작게 느껴질 수 있겠지만 수천, 수만개의 객체들이 생성되는 애플리케이션에서 객체당 4~8byte 절약은 메모리 절감 효과를 기대할 수 있다. 이번 포스팅에서는 JOL(Java Object Layer)를 사용하여 정말 객체의 헤더 사이즈가 줄어드는지 확인해 보자.

ThreadLocal의 개선: Java Scoped Value 가이드

java 21 부터 preview기능으로 시작한 범위 지정 값(이하 scoped value) API가 java 25부터 정식 기능으로 채택되었다.
java scoped value API는 메서드 매개변수를 사용하지 않고 메서드에 안전하고 효율적으로 데이터를 공유할 수 있도록 한다.
특히 java21 부터 도입된 가상 스레드를 사용할 때 ThreadLocal을 사용하면서 발생할 수 있는 문제에 대해서 scoped value 기능은 ThreadLocal에 대한 문제들을 해결할 수 있을 것이다.
이번 포스팅에서는 scoped value에 대한 도입 배경과 ThreadLocal 사용에 대한 문제와 함께 scoped value를 사용하는 방법에 대해서 정리해 보고자 한다. 샘플코드는 Java21 (preview)로 작성하였다.