-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add post '[Java] Static Object는 GC 의 대상일까? (permgen, metaspace, jeps1…
…22, java8)'
- Loading branch information
1 parent
c5a4ca0
commit 569b13d
Showing
1 changed file
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
layout: post | ||
title: "[Java] Static Object는 GC 의 대상일까? (permgen, metaspace, jeps122, java8)" | ||
categories: [스터디-자바, 개발] | ||
tags: [자바, java, permgem, metaspace, static, jeps122, GC, garbage collector] | ||
date: 2024-04-29 11:50:00 +0900 | ||
toc: true | ||
--- | ||
|
||
## 개요 | ||
|
||
Static Object의 경우에는 GC(garbage collector) 에 포함되지 않는다는 글이 인터넷 상에 많이 돌아다닌다. java 7 이전의 경우에는 static object가 permanent generation (permgen) 에 있었기 때문에 맞는 설명이라고 볼 수 있다. | ||
|
||
하지만 java 8 부터 permanent generation (permgen) 이라는 공간이 사라짐에 따라 static object는 java heap 으로 옮겨졌다. | ||
|
||
그런데 여기서 조금 더 생각해 볼 부분은 java heap 에 있는 객체들은 GC의 영향을 받게 된다는 것이다. 그러면 Static Object는 GC의 영향을 받는걸까 안받는걸까? | ||
|
||
## 본문 | ||
|
||
### permanent generation (permgen) 은 왜 사라졌을까? | ||
|
||
우선 위 내용에 대해서 이야기 해보려 한다. | ||
|
||
> Perm 영역은 보통 Class의 Meta 정보나 Method의 Meta 정보, Static 변수와 상수 정보들이 저장되는 공간으로 흔히 메타데이터 저장 영역이라고도 한다. | ||
permgen 은 고정된 메모리 공간이다. 따라서 java 7 까지는 이 공간에 많은 데이터가 들어오게 되면 다음과 같은 에러가 발생되었다. | ||
|
||
``` | ||
java.lang.OutOfMemoryError: PermGen space | ||
``` | ||
|
||
java 8 부터는 이러한 에러를 막고자 permgen을 제거하였다. | ||
|
||
그리고 클래스와 메소드의 메타 정보는 Native 영역의 Metaspace 영역으로 이동하였고, Static Object는 Java Heap 영역으로 이동하였다. | ||
|
||
### Static Object는 Java Heap 영역으로 이동되었다. | ||
|
||
그러면 다음과 같이 생각해볼 수 있는걸까? | ||
|
||
1. static object는 java heap 영역으로 옮겨졌다. | ||
2. java heap은 GC의 대상이다. | ||
3. 따라서, static object는 GC의 대상이다? | ||
|
||
이에 대해 맞는지 확인해보았다. | ||
|
||
### Static Object 가 GC 의 대상이 되는 경우 | ||
|
||
찾아보니 다음과 같은 경우에 Static Object 가 GC 의 대상이 된다고 한다. | ||
|
||
- 참조가 없는 경우: 더 이상 어떤 객체도 static object를 참조하지 않는 경우 | ||
- 의도적으로 참조변수에 null 을 대입한 경우이다. | ||
- **클래스 로더가 언로드된 경우**: 해당 static object를 포함하는 클래스 로더가 더 이상 사용되지 않는 경우 | ||
|
||
1번의 경우에는 이해가 된다. 더 이상 사용할 수 없는거니깐. 그런데 2번의 경우가 알기 어려운 부분이다. | ||
|
||
### 클래스 로더 | ||
|
||
일반적으로 개발자가 직접 클래스 로더와 클래스 로딩과 언로딩 에 대해서 신경쓰지 않아도 된다. 하지만 계속 알아보았다. | ||
|
||
우선 클래스 로더는 다음과 같은 일을 한다. | ||
|
||
> **클래스 로더** | ||
> | ||
> 클래스 로더는 Java Runtime Environment의 일부이다. JVM이 클래스를 요청하면 클래스 로더는 클래스를 찾고 정규화된 클래스 이름을 사용하여 클래스 정의를 런타임에 로드한다. | ||
클래스 로더는 다음과 같은 종류가 있다. | ||
|
||
- **내장 클래스 로더 (Built-in Class Loader)** | ||
- **부트스트랩 클래스 로더 (Bootstrap Class Loader)** : JDK 내부 클래스를 로드 | ||
- **확장 클래스 로더 (Extension Class Loader)** : JDK 확장 디렉토리를 로드 | ||
- **어플리케이션 클래스 로더 (Application Class Loader)** : 애플리케이션 레벨 클래스를 로드 | ||
- **커스텀 클래스 로더 (Custom ClassLoader)** : 사용자 구현 클래스 로더 | ||
|
||
#### 클래스 로더가 언로드 되는 경우 | ||
|
||
내장 클래스 로더의 경우에는 일반적으로 jvm이 종료될 때 까지 살아있는다. 그리고 클래스 로더는 살아있는 동안 계속 static object 를 참조한다. | ||
|
||
커스텀 클래스 로더의 경우 사용자 구현에 따라 클래스 로더가 언로드 될 수 있긴 하다고 한다. (하지만 일반적인 경우는 아닐 것이다.) | ||
|
||
## 정리 | ||
|
||
이론상으로 static class 는 GC에 의해서 처리 대상이 될 수 있지만, 현실적으로는 일부러 의도 하지 않는 이상 거의 힘들다고 할 수 있다. | ||
|
||
따라서 static object를 사용할 때는 메모리 누수가 발생되지 않도록 주의해야 하겠다. | ||
|
||
## 참고 | ||
|
||
- [JEP 122: Remove the Permanent Generation](https://openjdk.org/jeps/122) | ||
- [JDK 8에서 Perm 영역은 왜 삭제됐을까](https://johngrib.github.io/wiki/java8-why-permgen-removed/#fnref:compare) | ||
- [Are static fields open for garbage collection?](https://stackoverflow.com/questions/453023/are-static-fields-open-for-garbage-collection) | ||
- [Class Loaders in Java](https://www.baeldung.com/java-classloaders) | ||
|
||
### 추가 정보 | ||
|
||
위의 클래스 로더의 분류는 java 8 기준이다. | ||
|
||
java9 에서 [Jigsaw 프로젝트](https://openjdk.org/projects/jigsaw/)를 통한 모듈 시스템이 적용되면서 세부사항이 변경되었다. | ||
클래스 로더 이름도 Extension Class Loader 는 Platform ClassLoader로, Application Class Loader은 System ClassLoader로 바뀌었다. | ||
동작 방식은 거의 같다. 궁금하면 아래의 참조 링크를 보자. | ||
|
||
- [[Java] JVM 클래스 로더 - java9 변경사항 포함](https://jerry92k.tistory.com/64) |