Language 65

Java 21의 주요 패치 내용 살펴보기!

이번 포스팅에서는 Java 21이 2023년 9월(작성일 기준 이번달)에 출시한다. 개인적으로 Java 21의 패치 내용이 되게 인상깊은데 Java 21 버전의 변경사항에 대해 알아보자. SequencedCollection 기존에 List에서 첫 번째 요소와 마지막 요소를 구할 때는 아래와 같이 코드를 작성했다. String first = list.get(0); // 첫 번째 요소 String last = list.get(list.size() - 1) // 마지막 요소 이런 부분들 구현을 외부에 노출하므로 가독성이 많이 떨어진다. Java 21부터는 SequencedCollection이라는 인터페이스를 제공한다. public interface SequencedCollection extends Collec..

Language/Java 2023.09.10

JVM 옵션으로 튜닝 이해하기!

JVM 튜닝에 앞서 고려해야 할 점이 성능 중 어떤 부분을 우선할 것인가를 정해야 한다. 일반적으로 성능이란 TPS와 Latency로 나뉜다. 1. GC 알고리즘 GC 알고리즘을 예로 들면 처리량(TPS)이 목적이면 Parallel GC, 응답 시간이 목적이면 CMS GC, G1 GC가 유리하다. Parallel GC는 Full GC를 수행하면서 GC 소요 시간이 길지만 빈도가 적어서 총 STW 시간이 적다. 그래서 처리량이 높다. CMS, G1 GC의 경우 GC를 짧지만 빈번하게 수행하므로 처리량이 낮지만 응답시간이 빠르다. 추가로 CPU Core의 코어가 싱글이라면 Serial GC를 사용할 수 있고, CPU Core가 멀티 코어이고 Ram이 4GB 이상이라면 한 번에 여러개의 객체를 처리할 수 있는..

Language/Java 2023.08.01

메일 발송 시 OOM 해결하기! (with. FilterOutputStream)

평화롭던 어느날 메일 API에서 OOM이 터졌다. 발생한 End-point는 메일 발송으로 확인했다. 메일 원문은 40MB였고 개발 서버에서 테스트를 해봤다. 동일 본문으로 메일 발송 요청 1번에 결과 메모리 사용량이 117MB 정도 급증했다. 세부적으로는 2단계 메모리가 튀는 것으로 확인된다. 1차: 724MB -> 761MB 2차: 761 MB -> 841MB 바로 의심했던 것이 발송 이벤트였다. 비동기 이벤트가 두 건 발행되고 있었다. Forward Event Archive Event Line Separator 확인 결과 1. 발송, 2. 포워드 이벤트 핸들러, 3. 아카이브 이벤트 핸들러에서 아래 로직을 수행한다. 코드를 보면 ByteArrayOutputStream에 eml 파일 내용을 저장한다...

Language/Java 2023.07.24

JavaMail API 튜닝기! (메모리 성능 개선!)

이슈 Handle dispatch failed: nested exception is java.lang.OutOfMemoryError: Java heap space 어느날 특정 end-point에서 OOM이 터졌다. 아직까지 일부 사용자에게만 운영중인 서버라서 OOM이 터지는 것은 뭔가가 잘못되었다는 것을 의미한다. 리소스를 확인한 결과 실제로 메모리가 들쑥날쑥했고, OOM으로 인해 파드가 여러번 재실행되었다. 본문 내용 해당 본문을 확인해본 결과 아래와 같았다. 원문 크기: 38MB Part (첨부파일): 총 10개 - 하나 당 3~4MB 정도 첨부파일 조회 Flow 아래는 사용자가 Java-Mail-API를 사용하는 해당 서버에서 첨부파일을 조회할 때 발생하는 동작이다. 해당 원문과 Flow를 그려보니..

Language/Java 2023.07.19

Java - (JDK17에서는) String vs StringBuilder

Java 관련된 질문 중 String과 StringBuilder의 차이를 묻는 경우가 많다. 우리는 잘 알고 있는가..? 흔히 알려진 Java 관련 질문 중에서도 잘못된 질문과 답이 아주 많다고 생각한다. 대표적인 것 중 CheckedException과 UncheckedException의 대표적인 차이가 트랜잭션이 롤백된다는 것이다. 사실 CheckedException과 UnCheckedException은 근본적으로 트랜잭션과 아무 관련이 없다 (https://www.youtube.com/watch?v=_WkMhytqoCc) (무지성으로 공부하면서 Ctrl + C, Ctrl + V 한 결과..) String과 StringBuilder의 차이도 너무 무지성으로 외우는 경우가 많다. (나도 그랬다.) Str..

Language/Java 2023.04.04

JAVA - 문자열 비교에서의 시간 복잡도

삼성에서 주관하는 알고리즘 특강에서 라빈-카프 알고리즘에 대해서 배웠다. 그런데 한 가지 의문 사항이 생겼다. 문자열을 equals로 비교하는 것이 O(1)일텐데 왜 굳이 해시로 바꿔서 비교를 해야 하냐는 것이었다. (밑에 작성했지만 이는 사실이 아니었다!!) String.Equals String 인스턴스의 equals 메서드를 살펴봤다. (JDK 13 기준) 해당 메서드에서는 StringLatin1.equals() 메서드를 호출하고 있다. StringLatin1.equals() 메서드를 보자! bytes 배열 요소를 전부 비교하고 있음을 알 수 있었다. 참고로 String의 value 타입은 Jdk 버전마다 구현이 다르다. jdk 8의 경우에는 아래와 같이 char 배열을 사용하고, 아래와 같이 비교하..

Language/Java 2023.02.14

Java - 불변 객체(Immutable Object) 사용을 지향해야 하는 이유! (feat. final 키워드)

Clean Code나 Effective Java는 물론이고, 개발을 잘하는 팀의 얘기를 들으면 불변(Immutable) 객체의 필요성이 빠지지 않는다. 왜 불변 객체가 중요한 지 알아보자. 불변(Immutable) 객체 불변 객체란 객체 생성 이후 내부의 상태가 변하지 않는 객체이다. 가령 JPA에서 Embedded로 사용하는 Value Object를 예로 들 수 있다. @EqualsAndHashCode public class Money { private int value; public Money(int value) { this.value = value; } public int getValue() { return value; } public Money multiply(int multiplier) { re..

Language/Java 2022.11.11

Java - String Constant Pool이란 무엇일까?

Java에서 String 객체를 생성하는 방법은 크게 2가지가 있다. String literal(큰 따옴표 " ") new 연산자 방법 비교 String str1 = "abcd"; String str2 = "abcd"; System.out.println(str1 == str2); // true String literal을 사용하면 동일성 비교를 할 때 true가 나온다. String str1 = new String("abcd"); String str2 = new String("abcd"); System.out.println(str1 == str2); // false new 연산자로 생성한 String에 대해서 동일성 비교를 하면 false가 나온다. 우선 동일성(==)에 대해서 알고 가자. 동일성은 두 ..

Language/Java 2022.11.09

Java - ThreadLocal 동작 원리 이해하기! (+ 주의사항)

지난 번에 샤딩을 앱 서버에서 처리하기 위해 ThreadLocal이라는 공간에 매핑될 DB 서버 정보를 넣어줬다. https://jaehoney.tistory.com/180 그렇다면 ThreadLocal은 도대체 어떻게 동작하는 걸까..? 자세히 알아보자. ThreadLocal ThreadLocal은 java.lang에서 지원하는 클래스로 Thread-Safety하다고 알려져있다. 나는 'ThreadPool의 각 Thread는 ThreadLocal이라는 공간을 가진다. ThreadLocal은 하나의 인스턴스로 접근할 수 있고, 멀티 쓰레드 환경에서도 안전하게 동작한다.' 정도로 이해했었다. 그런데 어떻게 그런 것이 가능한 지 의문이 있었다. ThreadLocal 내부를 분석해보면 ThreadLocalMa..

Language/Java 2022.11.06

JVM - GC 알고리즘 알아보기! (feat. JDK 버전 별 Default)

나는 Java 버전을 고를 때 주로 LTS 버전(현재 기준 17)을 선호한다. 그렇다면 해당 버전(17)에서는 JVM의 Garbage Collection(GC)가 어떤 식으로 동작할까? docker run --cpus=1 --rm -it eclipse-temurin:17 java -Xlog:gc* -version [0.004s][info][gc] Using Serial docker run --cpus=2 --rm -it eclipse-temurin:17 java -Xlog:gc* -version [0.007s][info][gc] Using G1 JDK 17 버전 기준으로는 CPU가 1개라면 Serial GC가 실행되고, CPU가 2개 이상이라면 G1 GC가 실행된다. (사실 JDK 9 버전 이후로 동일하..

Language/Java 2022.11.06