📌 섹션 7 : 그밖에, 섹션 8 : 마무리

➕ 애노테이션의 변화

1. 타입 선업부에 사용

  • ElementType.TYPE_PARAMETER
    : 타입파라미터에만 애노테이션을 사용할 수 있다.
  • ElementType.TYPE_USE
    : 타입파라미터 뿐만 아니라 타입에도 애노테이션을 사용할 수 있다.
// 애노테이션 생성
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface Chicken {
}

// 애노테이션 사용
public static void main(@Chicken String[] args) throws @Chicken RuntimeException{
    List<@Chicken String> names = Arrays.asList("haeny");
}

static class FeelsLikeChicken<@Chicken  T> {
    public static <@Chicken  C> void print(@Chicken  C c){
    }
}

2. 중복 사용

@Repeatable 을 사용해서 중복사용 가능하게 설정할 수 있으며, 해당 애노테이션을 사용하기 위해서는 중복으로 사용할 애노테이션을 포괄하는 컨테이너 개념의 애노테이션이 있어야 한다.

// Chicken 애노테이션 생성
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@Repeatable(ChickenContainer.class)
public @interface Chicken {
    String value();
}

// Chicken 애노테이션을 포괄하는 ChickenContainer 애노테이션 생성
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface ChickenContainer {
    Chicken[] value();
}

// 애노테이션 사용
@Chicken("양념")
@Chicken("마늘간장")
public class App {

    public static void main(String[] args) {
        // #1
        Chicken[] chickens = App.class.getAnnotationsByType(Chicken.class);
        Arrays.stream(chickens).forEach(c -> System.out.println(c.value()));

	// #2
        ChickenContainer chickenContainer = App.class.getAnnotation(ChickenContainer.class);
        Arrays.stream(chickenContainer.value()).forEach(c -> System.out.println(c.value()));
    }
}

➕ 배열 병렬 정렬

public static void main(String[] args) {
    int size = 1500;
    int[] numbers = new int[size];
    Random random = new Random();

    /*
    * Arrays.sort 는 Single Thread 로 Dual-Pivot Quicksort 를 사용하여 정렬한다.
    * */
    IntStream.range(0, size).forEach(i -> numbers[i] = random.nextInt());
    long start = System.nanoTime();
    Arrays.sort(numbers);
    System.out.println("serial sorting took : " + (System.nanoTime() - start));

    /*
    * Arrays.parallelSort 는 ForkJoin common pool 을 사용하여,
    * 배열을 쪼개어 병렬적으로 정렬하며, 실질적인 정렬 시에는 Arrays.sort 와 같은 정렬방식을 사용한다.
     * */
    IntStream.range(0, size).forEach(i -> numbers[i] = random.nextInt());
    start = System.nanoTime();
    Arrays.parallelSort(numbers);
    System.out.println("parallel sorting took : " + (System.nanoTime() - start));
}

➕ Metaspace

JVM의 여러 메모리 영역 중에서 PermGen 메모리 영역이 없어지고, Metaspace 영역이 생겼다.

1. PermGen

  • 클래스의 메타데이터를 담는 곳
  • Heap 영역에 속함
  • 기본값으로 제한된 크기를 가지고 있다

제한된 크기를 가지고 있기 때문에 클래스가 너무 많이 생성되어, GC를 하는데도 불구하고 크기를 넘어갈 경우 OutOfMemory 가 발생할 수 있다.

이러한 경우 PermGen 사이즈를 늘려주는 조치를 할 수도 있지만, 근본적인 원인을 해결하는 방법이라고 볼 수 없었음.

2. Metaspace

  • 클래스의 메타데이터를 담는 곳
  • Heap 영역이 아니라, Native 메모리 영역에 있다.
  • 기본값으로 시작되지만, 제한된 크기가 아니라 필요에 따라 계속해서 늘어날 수 있다.
  • Java8 부터는 PermGen 관련 Java옵션은 무시한다.

크기가 제한되어 있지 않기 때문에 필요에 따라서 계속해서 늘어날 수 있다. 최대값을 설정해 주거나 그렇지 않은 경우 모니터링이 필요할 것이다.

📖 REFERENCE

PermGen Elimination project is promoting - http://mail.openjdk.java.net/pipermail/hotspot-dev/2012-September/006679.html
[Java Memory Profiling에 대하여]
① JVM 메모리 이해와 케이스 스터디 - https://m.post.naver.com/viewer/postView.nhn?volumeNo=23726161&memberNo=36733075

[Java Memory Profiling에 대하여]
② 메모리 모니터링과 원인분석 - https://m.post.naver.com/viewer/postView.nhn?volumeNo=24042502&memberNo=36733075

Java 8: From PermGen to Metaspace - https://dzone.com/articles/java-8-permgen-metaspace

0개의 댓글