Java 14

[Java] Garbage Collection(4) - Young Generational GC, Old Generational GC

Young Generational GC 이번에는 Eden 영역에 대해 더 알아보자. 참고로 HotSpot VM에서는 보다 빠른 메모리 할당을 위해서 2가지 기술을 사용한다. 첫 번째는 bump-the-pointer라는 기술이고, 두 번째는 TLABs(Thread-Local Allocation Buffers)라는 기술이다. bump-the-pointer는 Eden 영역에 할당된 마지막 객체를 추적한다. 마지막 객체는 Eden 영역의 맨 위(top)에 있는데, 다음에 생성되는 객체가 있으면 해당 객체의 크기가 Eden 영역에 넣기 적당한지만 확인한다. 만약 해당 객체의 크기가 적당하다고 판단되면 Eden 영역에 넣게 되고 새로 생성된 객체가 맨 위에 있게 된다. 따라서 새로운 객체 생성 시 마지막에 추가된 ..

Java 2022.04.14

[Java] Garbage Collection(3) - Generational GC

Generational GC GC는 다음의 2가지 가정에 따라 만들어졌다. 대부분의 객체는 금방 접근 불가능 상태(unreachable)가 된다. 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다. 이러한 가설을 Weak Generational Hypothesis라고 한다. 실제 통계로도 생성된 객체의 98%의 객체가 곧바로 쓰레기 객체가 된다고 한다. 이 가설의 장점을 최대한 살리기 위해서 HotSpot VM에서는 크게 2개로 물리적 공간(Young / Old)으로 나누었다. 이러한 경험적 사실들을 바탕으로 Generational GC가 디자인되었다. 우선 2번째 가설에 대해 살펴보면, Old 영역에는 512 Bytes의 덩어리(chunk)로 되어 있는 카드 테이블이 존재한다. 카드 테이블에는 ..

Java 2022.04.13

[Java] Garbage Collection(2) - 포인터 추적 방식

포인터 추적 방식 포인터 추적 방식이란 한 개 이상의 변수가 접근 가능한 메모리는 앞으로 사용할 수 있는 메모리로 간주하고 그 밖의 메모리를 해제하는 방식을 의미한다. 대부분의 GC는 포인터 추적 방식을 사용한다. 포인터 추적 방식의 종류 포인터 추적 방식에는 여러 가지 방법이 존재하는데 그 종류를 살펴보자. 표시하고 쓸기(Mark and Sweep) 표시하고 쓸기는 가장 단순한 방식이다. 먼저 각 메모리 할당 영역에 표시를 위해 1 비트의 메모리를 남겨둔다. 표시 단계에서 모든 변수가 가리키는 영역을 사용 중으로 표시하고 그 영역에서 가리키는 영역 또한 사용 중으로 표시한다. 이처럼 모든 메모리 영역을 표시하고 나면 표시되지 않은 영역은 접근 불가능한 메모리 영역이 된다. 접근 불가능한 메모리 영역들은..

Java 2022.04.12

[Java] Garbage Collection(1) - 개요

Garbage Collection이란? Garbage Collection이란 메모리 관리 기법 중의 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요 없게 된 영역을 해제하는 것이다. JVM 메모리 구조 GC의 종류를 살펴보기 전에 JVM 메모리 구조를 먼저 알아보자. JVM의 메모리 구조는 크게 Heap / Perm / Thread로 나눌 수 있다. Heap은 다시 Young(New) 영약과 Old 영역으로, Young 영역은 다시 Eden / Survivor1 / Survivor2로 나눌 수 있다. Young 영역은 객체가 처음 생성 시 저장되는 영역을 나타낸다. 정확히는 new 연산자를 통해 생성되는 객체들은 Eden 영역에 저장된다. Old 영역은 Young 영역에 존재하던 객체들이 ..

Java 2022.04.11

[Java] Java 8의 특징(7) - 기타 변화들(어노테이션, 병렬 정렬, Metaspace)

어노테이션의 변화 자바 8부터 어노테이션을 타입 선언부에도 사용할 수 있게 되었다. 또한 어노테이션을 중복해서 사용할 수 있게 되었다. 타입에 사용할 수 있으려면 @Target에 TYPE_PARAMETER(타입 변수에만)나 TYPE_USE(모든 타입 선언부)를 지정하면 된다. 어노테이션을 중복으로 사용하기 위해서는 중복 사용할 어노테이션을 만들고, 중복 어노테이션 컨테이너를 만들면 된다. 이때 컨테이너 어노테이션은 중복 사용할 어노테이션과 @Retention 및 @Target이 같거나 더 넓어야 한다. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) @Repeatable(AnimalContainer.class) public @inter..

Java 2022.02.28

[Java] Java 8의 특징(6) - CompletableFuture

자바 Concurrent 프로그래밍 Concurrent 하다의 의미는 동시에 여러 작업을 할 수 있는 것을 의미한다. 예를 들어 유튜브를 보면서 게임을 한다거나 노래를 들으면서 코딩을 하는 것들이 Concurrent 한 것이다. 자바에서 지원하는 Concurrent 프로그래밍에는 다음과 같은 것들이 있다. 멀티 프로세싱(ProcessBuilder) 멀티 스레드(Thread / Runnable) 멀티 스레드는 Thread를 상속해서 다음과 같이 구현할 수 있다. public class ConcurrentClass { public static void main(String[] args) { HelloThread helloThread = new HelloThread(); helloThread.start(); ..

Java 2022.02.28

[Java] Java 8의 특징(5) - Date와 Time

자바 8에서 새로운 날짜와 시간 API의 등장 배경 기존에 사용하던 java.util.Date 클래스는 mutable 하기 때문에 thread safe하지 않다. 그리고 클래스 이름이 명확하지 않다. Date 클래스인데 시간까지 다룬다. 또한 버그가 발생할 여지가 많다. 타입 안정성이 없고 월이 0부터 시작한다는 문제가 있었다. 자바 8에서 새롭게 등장한 날짜와 시간 API에는 다음과 같은 특징이 있다. 기계용 시간과 인간용 시간으로 나눌 수 있다. 기계용 시간은 Epoch 시간(1970년 1월 1일 00:00:00 협정 세계시)부터 현재까지의 타임스탬프를 표현한다. 인간용 시간은 우리가 흔히 사용하는 연, 월, 일, 시, 분, 초 등을 표현한다. 타임스탬프는 Instant를 사용한다. 특정 지역의 날짜..

Java 2022.02.26

[Java] Java 8의 특징(4) - Optional

Optional(옵셔널) Optional은 자바 프로그래밍에서 굉장히 자주 보이는 NullPointerException을 방지하기 위해서 등장했다고 볼 수 있다. 자바에서 NullPointerException을 자주 보게 되는 이유가 뭘까? 그 이유는 null을 리턴할 수도 있는 객체를 참조할 때 null 체크를 깜빡했기 때문이다. 우선 다음 코드를 보자. public class PetStore { public String getBuyer(Pet pet) { Master master = pet.getMaster(); return master.getName(); } } 위 코드에서는 null이 총 세 군데에서 발생할 수 있다. 첫 번째는 pet이 null일 수도 있고, 두 번째는 master가 null일 ..

Java 2022.02.25

[Java] Java 8의 특징(3) - Stream

Stream(스트림) 스트림은 컬렉션에 관한 다양한 처리를 도와주는 API이다. 우선 다음 코드를 보자. animals.sort(Comparator.comparing(Animal::getAge)); for (Animal animal : animals) { if (animal.getAge() >= 10) { System.out.println(animal.getName()); } } 위 코드는 동물들을 나이순으로 정렬한 뒤 10살 이상인 동물들의 이름을 출력하고 있다. 이 간단한 코드를 스트림을 이용해서 다음과 같이 바꿀 수 있다. animals.stream() .sorted(Comparator.comparing(Animal::getAge)) .filter(animal -> animal.getAge() >=..

Java 2022.02.23

[Java] Java 8의 특징(2) - 기본 메서드와 스태틱 메서드

인터페이스의 기본 메서드와 스태틱 메서드 자바 8부터 인터페이스에 메서드 선언이 아니라 다음과 같이 구현체를 정의할 수 있게 되었다. public interface Animal { void move(); default void sleep() { System.out.println("Sleep..."); } } default 키워드를 이용해 기본 메서드를 정의할 수 있다. 재정의를 강제했던 추상 메서드와는 달리 기본 메서드는 구현 클래스에서 재정의를 할 필요가 없다. 물론 필요에 따라 재정의도 가능하다. 기본 메서드의 장점은 구현 클래스를 건드리지 않고 새로운 기능을 추가할 수 있다는 점이다. 해당 인터페이스를 구현한 모든 클래스에 공통된 기능이 생겨야 한다면 인터페이스에 기본 메서드를 정의하면 된다. 기본..

Java 2022.02.22