구글에 검색해보면 java8 부터 permgen 영역이 meta space로 바뀌었다고 한다. meta space로 바뀌면서 native 메모리를 쓰게 되었다는 것.
많은 글들이 meta space로 바뀌었다고 알려준다. 바뀐건 알겠어. 근데 왜 바뀌었을까에 대한 답이 없다. 그거 글을 읽으며 유추해볼 수 있ㅇ 무슨 문제가 있었기에 바뀌었을까?
위의 기반 상식을 모른다면 이해하기 어려울 수 있다. 내가 그랬다. 그래서 기반 지식은 중요하다. 지난 글 마지막에 아기 돼지 삼형제 이야기 했던 것처럼 벽돌로 차곡 차곡 지은 집은 늑대의 바람에도 무너지지 않는다. 결론은 기반이 되는 기초 지식들은 벽돌을 쌓아 집을 짓는 것과 같다는 것이다. 그래서 다시 한번 강조하자면 기반 지식은 중요하다.
JVM 구조와 동작원리는 다른 글들을 찾아보면 된다. JVM을 설명하면 이 글의 의도에 벗어날 수 있으므로 필요한 부분만 뽑아내어 설명!
프로세스와 스레드
프로세스는 프로그램 단위이다.
스레드는 프로세스 안에서 일하는 작은 실행 단위이다.
그래서 프로세스 안에는 1개 이상의 스레드가 존재할 수 있는 것이다.
더 쉽게 비유하자면
회사 -> 컴퓨터
각 부서 -> 프로세스
각 부서의 팀원 -> 스레드
회사에는 여러 부서가 있다. 영업팀, 개발팀, 디자인팀 등등
각 부서는 프로세스와 같다. 하나의 프로그램 단위와 같은 것.
각 부서에서 실제로 일하는 팀원들 한 명, 한 명이 곧 스레드와 같다.
한 팀에 여러명의 팀원이 있는 것
-> 멀티스레드라고 한다.
영업 팀의 일이 많아져서 영업 팀을 만들어서 영업 1팀, 영업 2팀이 생겼다.
-> 이것은 멀티 프로세스
JVM 동작 구조
내가 만든 java파일이 어떻게 실행되는지 알아야한다.
크게 이렇게 동작한다.
오늘 내용의 중심은 클래스파일이 클래스 로더를 통해 Runtime Data Area의 method areas 배치된다는 것. 이것을 중점적으로 알아볼 것이다.
자바는 기본적으로 싱글 프로세스의 멀티 스레드이다.
하나의 프로세스이기 때문에 여러 스레드들이 공유해서 사용하는 영역들이 있고 각 스레드마다 혼자 사용하는 것들이 존재한다.
공유해서 사용하는 영역들이 바로
각 스레드들은 method area에 있는 클래스파일을 공유해서 쓸 수 있다. 그러면 heap영역에 생성된 객체도 다른 스레드에서 쓸 수 있는 건가? 여기서 헷갈리면 안되는 것은 스레드1이 heap영역에 생성한 객체가 공유되어서 스레드2가 쓸 수 있다는 말이 아니다. heap라는 메모리 공간을 공유한다는 것이다.
그렇다면 Permgen 영역은 무엇일까?
Java7까지 Runtime data area에 있던 영역으로 Permanent Generation의 역할은 method area와 같다. 클래스의 메타데이터나,static 변수와 상수 정보들이 저장되는 공간이다.
Permgen 영역에서 static은 무슨 문제가 있었을까?
Permgen은 클래스의 메타데이터들이 저장되는 공간이였다. static 변수나 메서드는 클래스 수준의 변수로서 클래스의 모든 인스턴스들에게 공유되는 특성이 있다. 그래서 static 변수와 메서드의 생명 주기는 해당 클래스가 로딩된 시점부터 프로그램이 종료될 때까지 였다. 즉, static은 계속 메모리를 잡아 먹게 되는 것이였다.
java8부터 static 관련 영역이 크게 바뀌다
Permgen은 또한 문제가 있었는데 그것은 바로 사이즈가 제한 되어있다는 것이였다. 위의 문제와 같은 맥락이며, 제한된 사이즈에서 클래스가 갑자기 많이 생성되고 static 데이터들이 남아있다면 OOM이 날 수 밖에 없던 것이였다.
이러한 문제를 해결하고 Java8부터는 Permgen을 없애고 meta space를 native 메모리에 만들었다. 이는 곧 Permgen의 영역의 사이즈 제한을 없앤것이라고 할 수 있다. 왜냐하면 meta space는 제한된 메모리가 아닌 동적으로 할당 받을 수 있기 때문이다.
또한 static관련된 것들은 Heap영역으로 이동하여 GC의 영향을 받도록하여 Permgen 보다 메모리 효율을 향상 시킬 수 있었다.
공부하며 느낀점
static 관련하여 이렇게 많은 고민을 했다는 것이 신기하다. 그만큼 문제가 생겼으니 static 관련하여 메모리 영역도 바꾸었다고 생각한다.
개인적으로 공부하면서 자꾸 딴길로 샐때가 많은데,
공부하면서 계속 목적 감각과 능동 감각을 잃지 않도록 의식하면서 공부해야겠다.
이번에 공부하게 되면서 자바 프로그램이 실행되는 과정을 확실하게 알 수 있었다. 특히 매번 어설프게 알던 클래스가 어떻게 되는지, Runtime data area는 무엇인지 excute engine의 역할은 무엇인지 등 확실하게 공부할 수 있는 시간이 되었다.
더 열심히하고 싶고 잘하고 싶다. 정말 잘하고 싶다. 탁월해지고 싶다.
참고 자료