GPT Archiving

펌젠과 메타스페이스

99duuk 2025. 4. 15. 18:06

1.  "펌젠이 뭐야? 그럼 메타스페이스는? 그 둘의 차이에 대해 말해봐."

1) 펌젠(PermGen)이란?

펌젠은 Permanent Generation의 약자로, Java 7까지 JVM의 힙 메모리 영역 중 하나였습니다. 이곳은 주로 클래스 메타데이터정적 데이터를 저장하는 데 사용됐어요. 구체적으로:

  • 클래스 메타데이터: 클래스 정의(예: 클래스 이름, 메서드 정보, 필드 정보 등).
  • 정적 변수: static으로 선언된 변수나 상수.
  • 인턴드 문자열(String Interning): 문자열 풀에 저장된 문자열 객체(예: "hello".intern()).
  • 기타: 메서드 영역과 관련된 일부 데이터.

펌젠은 힙 메모리 안에 고정된 크기로 할당되었기 때문에, 크기가 제한적이었어요. 그래서 클래스를 많이 로드하거나 정적 객체가 많아지면 "OutOfMemoryError: PermGen space" 오류가 자주 발생했죠. 이게 펌젠의 가장 큰 단점이었어요.

2) 메타스페이스(Metaspace)란?

메타스페이스는 Java 8부터 펌젠을 대체한 새로운 메모리 영역입니다. 펌젠과 비슷하게 클래스 메타데이터를 저장하지만, 몇 가지 중요한 차이가 있어요:

  • 위치: 메타스페이스는 힙 메모리가 아니라 네이티브 메모리(OS에서 직접 관리하는 메모리)에 할당됩니다.
  • 크기: 기본적으로 고정된 크기 제한이 없어요. 필요에 따라 동적으로 확장되거나 축소될 수 있습니다(물론, OS 메모리 한계는 존재해요).
  • 가비지 컬렉션: 메타스페이스도 가비지 컬렉션이 가능해서, 더 이상 사용되지 않는 클래스(예: 동적으로 로드된 클래스)가 정리됩니다.

메타스페이스 덕분에 펌젠에서 자주 발생하던 메모리 부족 오류가 크게 줄어들었어요. 하지만 메타스페이스가 무한정 커질 수도 있으니, 설정(예: -XX:MaxMetaspaceSize)으로 관리할 수 있습니다.

3) 펌젠과 메타스페이스의 차이

이제 두 영역의 차이를 정리해볼게요:

항목 펌젠(PermGen) 메타스페이스(Metaspace)
도입 시기 Java 7까지 사용 Java 8부터 사용
메모리 위치 힙 메모리 내 고정된 영역 네이티브 메모리(힙 외부)
크기 제한 고정된 크기(기본 64MB, 설정으로 조정 가능) 기본적으로 무제한(OS 메모리 한계까지 동적 확장)
오류 발생 OutOfMemoryError: PermGen space 빈번 메모리 부족 오류 드물음dcc7a4d5-0e53-11e7-bd8a-07ae519f73f1메모리 부족 오류 드물음
가비지 컬렉션 제한적(클래스 언로딩 드물음) 적극적(사용 안 되는 클래스 정리 가능)
설정 옵션 -XX:MaxPermSize, -XX:PermSize -XX:MaxMetaspaceSize, -XX:MetaspaceSize
왜 펌젠에서 메타스페이스로 바뀌었을까?

펌젠은 고정된 메모리 크기 때문에 동적으로 클래스를 로드하는 애플리케이션(예: 웹 서버, 스프링 프레임워크)에서 메모리 관리가 어려웠어요. 메타스페이스는 네이티브 메모리를 사용해 유연하게 확장 가능하고, 가비지 컬렉션도 개선돼서 현대적인 애플리케이션에 더 적합합니다.

결론

펌젠은 Java 7까지 클래스 메타데이터를 저장하던 힙 내 고정된 메모리 영역이었고, 메타스페이스는 Java 8부터 이를 대체해 네이티브 메모리를 사용하는 동적 메모리 영역이에요. 메타스페이스는 펌젠의 메모리 부족 문제를 해결하고, 더 유연하고 효율적인 메모리 관리로 바뀐 결과라고 볼 수 있습니다.

이렇게 설명드렸는데, 혹시 더 궁금한 점 있으시면 말씀해주세요!

 

 

 

 


2. "혹시 펌젠과 메타스페이스에 대해 여쭤봐도 될까요?"

 

 펌젠(PermGen)과 메타스페이스(Metaspace)는 자바 프로그램이 실행될 때 JVM이 메모리를 관리하는 방식과 관련된 중요한 개념이야. 하나씩 쉽게 풀어서 설명해줄게.

1) 펌젠(PermGen)은 뭐야?

펌젠은 "Permanent Generation"의 줄임말로, 예전 자바(Java 7까지)에서 클래스 정보를 저장하던 메모리 공간이야. 자바 프로그램은 클래스로 구성되잖아? 예를 들어, public class MyApp { ... } 같은 코드가 있으면, 이 클래스의 구조(이름, 메서드, 변수 등)가 펌젠에 저장돼.

펌젠에는 이런 것들이 들어가:

  • 클래스 정보: 클래스의 설계도 같은 데이터.
  • 정적 변수: static 키워드가 붙은 변수(예: static int count = 0;).
  • 문자열 풀: "Hello" 같은 문자열이 재사용되도록 저장된 곳.

근데 펌젠의 문제는 크기가 고정되어 있다는 거야. 예를 들어, 64MB로 설정해뒀는데 클래스가 너무 많아지면? 메모리가 꽉 차서 "OutOfMemoryError: PermGen space"라는 오류가 터져. 특히 스프링이나 톰캣 같은 서버 프로그램에서 자주 봤을 거야.

2) 그럼 메타스페이스는?

메타스페이스는 Java 8부터 펌젠을 대체한 업그레이드 버전이야. 역할은 펌젠과 비슷해—클래스 정보를 저장하지. 하지만 훨씬 똑똑해졌어. 차이점은:

  • 메모리 위치: 펌젠은 JVM의 힙 메모리 안에 있었는데, 메타스페이스는 네이티브 메모리(운영체제가 관리하는 메모리)로 옮겨갔어. 그래서 힙과 독립적이야.
  • 크기: 펌젠은 크기가 고정이었지만, 메타스페이스는 필요하면 자동으로 늘어나. 물론 OS 메모리 한계는 있지만, 훨씬 유연해.
  • 오류 감소: 펌젠의 악명 높은 메모리 오류가 메타스페이스에서는 거의 안 나와. 대신 메모리 사용을 잘 모니터링해야 해.

쉽게 비유하자면, 펌젠은 작고 꽉 찬 창고 같아서 물건(클래스)이 많아지면 터졌어. 메타스페이스는 무한 확장 가능한 클라우드 저장소 같은 느낌이야.

3)  차이는 뭐야?

핵심 차이를 표로 정리해볼게:

항목 펌젠 메타스페이스
언제 쓰였어? Java 7까지 Java 8부터
어디에 저장돼? 힙 메모리 안 네이티브 메모리(힙 밖)
크기 조절 고정(예: 64MB) 동적(필요하면 커짐)
오류 메모리 부족 오류 자주 발생 오류 드물음
관리 거의 안 정리됨 안 쓰는 클래스 정리됨(가비지 컬렉션)
실무에서 왜 중요할까?
  • 펌젠 시절: 서버 애플리케이션에서 클래스를 동적으로 로드하거나(예: 스프링 빈), 리플렉션을 많이 쓰면 펌젠이 금방 차서 서버가 다운됐어. 그래서 -XX:MaxPermSize 같은 옵션으로 튜닝했지.
  • 메타스페이스 시대: 요즘은 메타스페이스 덕분에 이런 문제가 훨씬 줄었어. 하지만 메모리 누수(ClassLoader Leak 같은 거)가 있으면 메타스페이스도 커질 수 있으니, 프로덕션 환경에서는 메모리 모니터링 툴(예: VisualVM, JConsole)을 써서 확인하는 게 좋아.
마무리

펌젠은 자바 초창기의 메모리 관리 방식이었고, 메타스페이스는 현대적인 애플리케이션의 요구에 맞춰 더 유연하게 바뀐 거야. 요즘은 메타스페이스 덕분에 개발자가 메모리 관리에 신경 쓸 일이 줄었지만, 그래도 기본 개념을 아는 건 중요해.


공통적인 추가 팁

  • 비유 활용: 펌젠은 고정된 책장, 메타스페이스는 확장 가능한 디지털 도서관으로 비유하면 이해가 쉬워요.
  • 실무 연결: 스프링, 히버네이트, 톰캣 같은 프레임워크에서 동적 클래스 로딩이 많으니, 메타스페이스 모니터링이 중요하다고 강조.
  • 설정 옵션: 펌젠은 -XX:MaxPermSize, 메타스페이스는 -XX:MaxMetaspaceSize로 관리 가능. 실무에서는 기본값으로 충분한 경우가 많음.