전 PermGen 후 Metaspace

Bruce Han·2022년 10월 3일
0

Java8-정리

목록 보기
20/20
post-thumbnail

이 포스팅의 코드 및 정보들은 강의를 들으며 정리한 내용을 토대로 작성한 것입니다.

PermGen의 퇴장과 Metaspace의 등장

Java 8 이전의 PermGen

PermGen이라고 불리는 곳은 Permanent Generation이라고 불리던 곳이며, 클래스 정보(메타데이터)를 담아뒀던 저장소이자 메모리 공간이었다.

그래서 클래스를 로딩할 때, 클래스의 이름/static 멤버들 등의 정보들을 쭉 담으며, 클래스를 많이 쓰면 쓸수록 그 공간의 데이터가 쌓인다.

PermGen 이라는 공간이 원래는 Heap 영역의 일부였다. Heap영역에서는 Java에서 JVM 안에 Runtime Data Area 안에 위치하여 메모리 공간을 관리한다. 또한 내부에는 Young Generation/Old Generation이 들어있다.

OS가 제공하는 메모리는 Native Memory라고 불리며, 그 위에 Java 명령어를 실행해서 어떤 프로그램이 실행되면 JVM이 관리하는 메모리 영역 중 Heap이라는 영역이 있다.

Heap 영역에는

  • Eden 영역
    • Young Generatio이라는 만들어진지 얼마 되지 않은 객체들이 산다.
  • Old Generation 영역
    • 만들어진지 오래된, 오래 살아있는 객체들이 이쪽으로 넘어온다.
  • PermGen
    • PermGen 영역은 항상 고정된 크기를 가지고 생성된다.
    • JDK 버전 / OS가 32bit인지 64bit인지에 따라서 달라지며, 보통 64MB ~ 128MB 사이로 기본값이 세팅된다.
    • 클래스 로딩을 많이 하거나 동적으로 클래스를 많이 생성하는 경우에 PermGen 영역이 꽉 차는 경우가 생긴다.
    • 만약 쭉 쌓이다가 넘치면 Garbage Collect를 하는데, 그래도 넘치면 메모리가 부족하다는 에러가 발생한다.
      • 그런 상황이 발생하면 일단 PermGen 사이즈를 늘리는데, 사이즈를 늘리는 것 자체는 딱히 해결책이 되지 않는다. 어디선가 클래스를 동적으로 만들고 있는데 정리가 되지 않는 것일 가능성이 높다. -> 이럴 때는 근본적으로 코드를 찾아서 해결해야 한다.

Java 8 이후의 Metaspace

Java 8 이후에는 Heap에 있던 PermGen 영역이 없어지고, Heap에는 Young Generation,Eden과 Old Generation 영역만 남게 된다.

사라진 PermGen은 Native Memory에 Metaspace라는 이름으로 자리잡게 된다.

이 Metaspace는 PermGen과는 비슷하게 초기 사이즈는 정해져 있지만 고정된 사이즈가 없다.
Metaspace의 사이즈에 대해서는 걱정할 필요는 없지만 모니터링은 해봐야한다. 너무 지나치게 늘어나면, 필요한 만큼 기본값이 늘어나 OS에 있는 Native Memory가 차게 된다.
꽉 차면 전체 서버가 죽게 된다. 즉, 서버의 메모리가 부족해지는 상황이 발생하는 것이다.

최소한으로 해줘야 하는 것은 Metaspace의 최댓값을 설정하는 것이다.

  • -XX:MaxMetaspaceSize=N이 옵션으로 Metaspace의 사이즈를 지정해줄 수 있다.

만약 중간에 사이즈를 조금 시작했다가 늘리는, Operation 자체도 줄이고 싶다면 애쵸에 -XX:MetaspaceSize=N-XX:MaxMetaspaceSize=N만큼의 값을 주면 된다.

그러나 효율적으로 쓰려면 모니터링을 해서 Jstat이라는 커맨드가 제공하는 옵션을 사용하면 이걸로도 Metaspace에 얼만큼의 Memory를 쓰고 있는지에 대한 모니터링이 가능해진다.

그런 것들을 모니터링해서 사이즈를 설정할 적절한 값을 찾으면 된다. 값을 찾아서 그걸 가지고 Max로 정해놓으면 감지할 수 있다.

Max값이 딱 차면서 GC도 감당하지 못하는 경우는 어딘가에서 누수가 있다는 것이다.
어디선가 클래스를 만들어내고, 로딩하는 곳에서 무슨 일이 있으면 그걸 찾아서 해결해야 한다.

정리

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

  • PermGen

    • permanent generation, 클래스 메타데이터를 담는 곳
    • Heap 영역에 속함
    • 기본값으로 제한된 크기를 가지고 있음
    • -XX:PermSize=N, PermGen 초기 사이즈 설정
    • -XX:MaxPermSize=N, PermGen 최대 사이즈 설정
  • Metaspace

    • 클래스 메타데이터를 담는 곳
    • Heap 영역이 아니라 Native 메모리 영역임
    • 기본값으로 제한된 크기를 가지고 있지 않으며, 필요한 만큼 계속 늘어난다.
    • Java8부터는 PermGen 관련 Java 옵션은 무시한다.
    • -XX:MetaspaceSize=N, Metaspace 초기 사이즈 설정
    • -XX:MaxMetaspaceSize=N, Metaspace 최대 사이즈 설정

Reference

profile
만 가지 발차기를 한 번씩 연습하는 사람은 두렵지 않다. 내가 두려워 하는 사람은 한 가지 발차기를 만 번씩 연습하는 사람이다. - Bruce Lee

0개의 댓글