Java GC : 왜 두 개의 생존 지역입니까?
Sun / Oracle의 JVM의 경우 GC 알고리즘이 새로운 세대를 하나의 Eden 영역과 두 개의 생존 영역으로 나눈다는 것을 읽었습니다. 내가 궁금한 것은 왜 하나가 아닌 두 개의 생존 지역 이냐는 것입니다. algo는 Eden과 하나의 생존자 영역 사이에서 계속해서 핑퐁을 할 수 있습니다 (현재 두 생존자 영역 사이에서하는 방식). 아니면이 접근 방식에 단점이 있습니까?
나는 JRockit의 GC 구현이 당신이 제안한 것처럼 단일 eden과 단일 생존자 공간으로 더 잘 작동한다고 믿지만 그것에 대해 인용하지 마십시오.
HotSpot JVM에 두 개의 생존 공간이있는 이유는 단편화를 처리 할 필요성을 줄이기 위해서입니다. 새 객체는 eden 공간에 할당됩니다. 모두 좋고 좋습니다. 그게 가득 차면 GC가 필요하므로 오래된 개체를 죽이고 살아있는 개체를 생존 공간으로 이동하여 한동안 성숙 할 수있는 곳에서 이전 세대로 승격됩니다. 지금까지는 여전히 좋습니다. 그러나 다음에 에덴 공간이 부족하면 수수께끼가 있습니다. 다음 GC가 나타나서 에덴과 생존자 공간의 일부 공간을 정리하지만 공간은 연속적이지 않습니다. 그래서 더 낫다
- 에덴의 생존자들을 GC가 지운 생존자 공간의 구멍에 맞추려고합니까?
- 조각화를 제거하기 위해 생존자 공간의 모든 개체를 아래로 이동 한 다음 생존자를 그 안으로 이동 하시겠습니까?
- "나사, 우리는 어쨌든 모든 것을 이동하고 있습니다"라고 말하고 두 공간의 모든 생존자를 완전히 분리 된 공간 (두 번째 생존자 공간)으로 복사하여 깨끗한 에덴과 생존자 공간을 남깁니다. 다음 GC에서 시퀀스를 반복 하시겠습니까?
질문에 대한 썬의 대답은 분명합니다.
2 개의 생존 공간의 역할은 사소한 가비지 수집 작업 후 역전됩니다.
두 개의 생존자 공간. 이들은 최소한 한 번의 작은 가비지 수집에서 살아남은 객체를 보유하지만 이전 세대로 승격되기 전에 도달 할 수 없게 될 또 다른 기회가 주어졌습니다. 그중 하나만 개체를 보유하고 다른 하나는 대부분 사용되지 않습니다.
소규모 가비지 수집 작업 중에 가비지로 확인 된 개체가 표시됩니다. 컬렉션에서 살아남은 에덴의 라이브 개체는 사용되지 않은 생존자 공간에 복사됩니다. 사용중인 생존자 공간에있는 살아있는 물체 (젊은 세대에 다시 되 찾을 기회가 주어짐)도 사용되지 않은 생존자 공간에 복사됩니다. 마지막으로, 사용중인 생존자 공간에서 "충분히 오래된"것으로 간주되는 살아있는 물체는 구세대로 승격됩니다.
사소한 가비지 수집이 끝나면 두 생존자 공간이 역할을 바꿉니다. 에덴은 완전히 비어 있습니다. 하나의 생존자 공간 만 사용 중입니다. 그리고 구세대의 점유율은 약간 증가했습니다. 라이브 개체는 작업 중에 복사되기 때문에 이러한 유형의 가비지 수집기를 복사 가비지 수집기라고합니다.
출처 : 위는 Charlie Hunt와 Binu John 의 Java Performance 83 페이지에서 발췌 한 것 입니다.
Young Generation : 단기간 살며 두 개의 공간으로 나뉘어 진 곳입니다.
Eden 공간 : 새 개체가 메모리 풀에 할당됩니다. 대부분의 객체는 생성 직후 역 참조되고 도달 할 수 없게된다고 가정합니다. 역 참조되지 않는 개체는 차세대 가비지 수집기에 의해 생존 공간으로 복사됩니다. 일부 특수한 경우에는 이전 세대 풀에 직접 복사 될 수 있습니다.
생존자 공간 : 이 두 개의 작은 공간은 젊은 세대 가비지 수집의 생존 대상을 유지합니다. 살아남은 개체는 한 생존자에서 다른 생존자로 (작은) 횟수 동안 복사됩니다. 이를 통해 더 역 참조 된 객체를 수집 할 수 있습니다.
구세대 : 수명이 긴 개체를 유지해야하는 가장 큰 메모리 풀. 개체가 생존자 공간을 벗어나면이 풀로 복사됩니다.
영구 생성 : 이 상당히 알려지지 않은 풀은 모든 클래스의 정보를 유지합니다. 대부분의 응용 프로그램에서는주의가 필요하지 않습니다. 클래스가 많은 일부 응용 프로그램에 맞게 조정해야 할 수 있습니다. 응용 프로그램이 클래스를 영구적으로로드 및 언로드하는 경우에도 약간의주의가 필요할 수 있습니다.
기타 장점 :
- 메모리 조각화
- GC 성능을 향상시킵니다.
자세한 내용을 이해하는 데 도움이 될 수있는 자세한 내용은 다음 링크를 참조하십시오.
http://www.scalingbits.com/javaprimer
http://java.sys-con.com/node/84695
현재의 모든 대답은 메모리 조각화에 대해 이야기하며 이는 GC에서 세대를 갖는 또 다른 이유입니다.
런타임은 "새 개체"를 가리키는 모든 "이전 개체"를 기록하며 "포인터"필드가 업데이트 될 때마다 수행됩니다. 그런 다음 "광부"GC가 완료되면 "새"개체 만 스캔하면됩니다.
수년에 걸쳐“새롭고”“오래된”것만으로는 충분하지 않다는 것이 밝혀졌으며,“중년”인 3 세대가있는 것이 좋습니다.
세대의 모든 인스턴스를 한 공간에서 다른 공간으로 복사하는 것과 메모리 주소 순서로 세대 공간의 시작 부분에 복사하는 것의 장점과 단점은 무엇입니까? 항목을 순서대로 처리하려면 항목 당 추가 포인터를 추가해야하지만 '생존자'공간 중 하나가 필요하지 않습니다.
두 명의 생존자는 표시 및 복사 알고리즘의 구현입니다. 이들은 젊은 세대를 위해 GC에서 사용됩니다. 여기 옵션 3 에서 Ryan이 언급했듯이
자바 객체의 힙 메모리 힙 메모리라는 영역에 생성 된 자바 객체 힙 메모리는 JVM 시작시 생성되고, 힙 메모리는 자바 애플리케이션 실행시 증가 또는 감소합니다. 힙 메모리가 가득 차면 가비지 수집기는 사용하지 않는 개체를 제거하므로 가비지 수집기는 새 개체를위한 공간을 만듭니다.
The heap memory is divided into two areas (or generations) called
1.young space. 2.old space.
1.In young space, there is Eden space for new Object and there are two Survivor Spaces(from and to), these two Survivor Spaces are always same size.
2.Survivor Spaces are used to store survival Objects.When the young space becomes full, garbage collector removes the unused objects by running a special young collection, where all objects that have lived long enough in the young space are promoted (moved) to the old space,thus freeing up the young space for more object allocation.
3.If Eden space is full,GC will run, if any objects are live in this Eden space, those are moved to Survivor Space.
4.In young space, GC normally use Copying Algorithm, which is fast, Everytime, survival Objects are copied to one of the Survivor Space.
5.If Survivor Space is full, rest of live Objects are directly copied to Old space.
6.In Old space, GC nornally use Mark-Compact Algorithm, which is slow but requires less memory.
7.When the old space becomes full garbage is collected there, a process called an old collection.In Old space, long live time Objects stay there.
8.Out of Memory will happen there is no space for new Object even GC done for OLD or Perm part.
9.Object is moved during Garbage Collection: eden -> survivor -> tenured(old space)
Objects start their journey in Eden of the Young Generation. When Eden fills up, so called Minor GC is performed: all application threads are stopped (stop-the-world pause), objects which are not used anymore are discarded and all other objects from the Eden are moved to the first Survivor space (S0). Next time a Minor GC is performed, the objects goes from S0 to the second Survivor space (S1). All live objects from Eden goes to S1 as well. Notice that it leads to differently aged object in the Survivor space – we have objects from Eden and objects which were already in the Survivor space. Next iteration of Minor GC moves the objects from S1 back to the S0, so the Survivor spaces switch every GC. Why do we have two Survivor spaces and why do we switch them? It’s pretty simple – when the object reaches certain age threshold, it is promoted to the Old Generation. It leads to Survivor space fragmentation which can be easily eliminated with moving all objects from S0 to S1 and back every Minor GC.
참고 URL : https://stackoverflow.com/questions/10695298/java-gc-why-two-survivor-regions
'development' 카테고리의 다른 글
PHP에서 정적 변수 / 함수를 언제 사용합니까? (0) | 2020.10.27 |
---|---|
TextBox에서 Enter 키 캡처 (0) | 2020.10.27 |
pom에 정의 된 Maven 속성에 액세스 (0) | 2020.10.27 |
본문을 포함하려면 HTTP PUT 요청이 필요합니까? (0) | 2020.10.27 |
ggplot2로 범례 알파를 설정하는 방법 (0) | 2020.10.27 |