JavaRush /Java Blog /Random-KO /Java의 가비지 수집기에 대한 추가 정보

Java의 가비지 수집기에 대한 추가 정보

Random-KO 그룹에 게시되었습니다
안녕하세요! 지난 강의에서 우리는 Java 언어에 내장된 메커니즘인 가비지 컬렉터에 대해 처음으로 알게 되었습니다. 프로그램이 실행되는 동안 백그라운드에서 작동하여 불필요해진 개체를 수집하고 나중에 삭제합니다. 이렇게 하면 나중에 새 객체를 생성하기 위한 메모리를 확보할 수 있습니다. 이번 강의에서는 그 작동 원리에 대해 자세히 살펴보겠습니다. 예를 들어, 객체가 어떻게 그리고 어느 시점에서 불필요하게 되는가? 그리고 가비지 수집기는 이에 대해 어떻게 알 수 있습니까? 우리는 이러한 질문에 답할 것입니다 :) 우리 강의는 개요에 가깝습니다. 이 자료는 외울 필요가 없습니다. 이 책은 메모리 작업과 가비지 수집기에 대한 시야를 넓히기 위한 것이므로 읽고 스스로 새로운 것을 배우는 것으로 충분할 것입니다 :) 가자! 가장 먼저 기억해야 할 것은 가비지 수집기가 프로그램과 병렬로 실행된다는 것입니다 . 그것은 그것의 일부가 아니며 별도로 기능합니다. 이것을 설명하기 위해 지난 강의에서 우리는 로봇 진공 청소기에 비유했습니다. 사실 항상 그런 것은 아니었습니다. 이전에는 가비지 수집기가 프로그램과 동일한 스레드에서 작동하도록 설계되었습니다. 그리고 일정에 따라 몇 분에 한 번씩 프로그램에 불필요한 개체가 있는지 확인하기 시작했습니다. 문제는 이 검사와 가비지 수집 중에 프로그램이 정지되어 실행되지 않았다는 것입니다. 당신이 사무실에 앉아 일하고 있다고 상상해보십시오. 그런데 청소 아주머니가 와서 방 바닥을 닦아야 합니다. 그녀는 당신을 컴퓨터 뒤에서 5분 동안 쫓아내고 당신은 그녀가 청소를 마칠 때까지 기다립니다. 이 기간 동안에는 일을 할 수 없습니다. 이것은 대략 가비지 수집기가 작동했던 방식입니다 :) 나중에 이 메커니즘이 변경되어 이제 가비지 수집기가 프로그램 자체의 작업 속도를 늦추지 않고 백그라운드에서 작동합니다. 객체에 대한 참조가 남아 있지 않으면 객체가 죽는다는 것을 이미 알고 있습니다. 그러나 가비지 수집기 는 실제로 . 첫째, 꽤 길 수 있습니다. 둘째, 그다지 효과적이지 않습니다. 결국 객체는 서로를 참조할 수 있습니다! 가비지 수집기에 대한 추가 정보 - 2그림은 3개의 객체가 서로 참조하지만 다른 객체는 참조하지 않는 예를 보여줍니다. 즉, 프로그램의 나머지 부분이 작동하는 데는 필요하지 않습니다. 가비지 수집기가 단순히 참조를 계산하는 경우 이 3개 개체는 모두 남아 있고 메모리를 확보하지 못할 것입니다. 해당 개체에 대한 참조가 있습니다! 우주선과 비교할 수 있습니다. 비행 중에 우주비행사들은 수리를 위해 예비 부품 목록을 확인하기로 결정했고 그중에서 일반 자동차의 스티어링 휠과 페달을 발견했습니다. 여기에는 분명히 필요하지 않으며 추가 공간을 차지합니다. 이러한 부품은 연결되어 있고 일부 기능을 가지고 있지만 우주선 작동의 틀 내에서는 불필요한 쓰레기이므로 제거하는 것이 좋습니다. 따라서 Java는 참조를 계산하지 않고 객체를 도달 가능한 유형 과 도달 불가능한 유형의 두 가지 유형으로 나누는 가비지 수집의 기반을 만들기로 결정했습니다.. 개체에 도달할 수 있는지 확인하는 방법은 무엇입니까? 독창적인 모든 것은 간단합니다. 도달 가능한 다른 객체가 참조하는 객체는 도달 가능합니다. 이로 인해 "접근성 체인"이 발생합니다. 프로그램이 시작될 때 시작되어 전체 작동 기간 동안 계속됩니다. 이는 다음과 같습니다. 가비지 수집기에 대한 추가 정보 - 4그림의 화살표는 프로그램의 실행 코드를 나타냅니다. 코드(예: main() 메서드)에서는 객체에 대한 참조가 생성됩니다. 이러한 개체는 새 개체를 참조할 수도 있고, 다른 개체 등을 참조할 수도 있습니다. 객체 링크 체인이 형성됩니다 . 이 링크 체인을 통해 "루트 링크", 즉 실행 코드에서 직접 생성된 개체에 도달할 수 있는 경우 해당 개체는 도달 가능한 것으로 간주됩니다. 우리 사진에서는 파란색으로 표시되어 있습니다. 그러나 개체가 이 체인에서 벗어난 경우, 즉 현재 실행 중인 코드의 변수 중 해당 개체에 대한 참조가 포함되어 있지 않고 "링크 체인"을 통해 해당 개체에 도달하는 것도 불가능합니다. 도달할 수 없는 것으로 간주됩니다. 우리 프로그램에서는 그러한 객체 두 개가 빨간색으로 표시됩니다. 참고: 이 "빨간색" 개체는 서로 연결되어 있습니다. 그러나 앞서 말했듯이 Java의 최신 가비지 수집기는 참조 계산을 수행하지 않습니다. 객체 에 도달할 수 있는지 또는 도달할 수 없는지 여부를 결정합니다 . 따라서 사진 속 빨간색 물체 두 개가 그의 먹이가 될 것이다. 이제 전체 프로세스를 처음부터 끝까지 살펴보고 동시에 Java에서 메모리가 어떻게 작동하는지 살펴보겠습니다. :) Java의 모든 객체는 이라는 특수 메모리 영역에 저장됩니다 . 일상 언어에서 "무더기"는 모든 것이 뒤죽박죽되어 있는 산더미 같은 물건을 의미합니다. 그러나 Java의 힙은 그렇지 않습니다. 매우 논리적이고 합리적인 구조를 가지고 있습니다. 어느 화창한 날, Java 프로그래머는 프로그램의 모든 개체가 비교적 간단한 개체"오래 지속되는" 개체라는 두 가지 유형으로 나눌 수 있다는 사실을 발견했습니다 . "오래 지속되는" 개체는 많은 가비지 수집에서 살아남은 개체입니다. 대부분 프로그램이 끝날 때까지 존재합니다. 그 결과, 생성된 모든 객체가 저장되는 공통 힙이 여러 부분으로 나누어졌습니다. 첫 번째 부분에는 아름다운 이름인 에덴 (성서의 "에덴 동산")이 있습니다. 이것은 객체가 생성된 후 이동되는 위치이기 때문에 훌륭한 이름입니다. 우리가 쓸 때 새로운 객체에 대한 메모리가 할당되는 부분이 바로 이 부분입니다.new. 많은 객체가 생성될 수 있으며, 이 영역의 공간이 부족해지면 첫 번째 "빠른" 가비지 수집이 시작됩니다. 가비지 수집기는 매우 똑똑하며 힙에 무엇이 더 있는지(가비지 또는 작업 개체)에 따라 작업 알고리즘을 선택합니다. 거의 모든 개체가 가비지인 경우 수집기는 "활성" 개체를 표시하고 이를 다른 메모리 영역으로 옮긴 후 현재 영역을 완전히 정리합니다. 쓰레기가 적고 대부분이 생물체로 점유되어 있는 경우에는 쓰레기를 표시하고 청소한 후 남은 물건을 정리합니다. 우리는 "컬렉터가 "살아있는" 개체를 표시하고 다른 메모리 위치로 옮긴다"고 말했지만 어느 것입니까? 최소한 한 번의 가비지 컬렉션에서 살아남은 모든 객체가 전송되는 메모리 영역을 생존 공간( Survival Space) 이라고 합니다 . 서바이벌 스페이스(Survival Space)는 차례로 세대 로 나누어진다 . 각 개체에는 발생한 가비지 수집 횟수에 따라 세대가 할당됩니다. 하나라도 있으면 '1세대'에 속하고, 5개가 있으면 '5세대'에 속합니다. Eden과 Survival Space는 함께 Young Generation 이라는 영역을 형성합니다 . Young Generation 외에도 힙에는 Old Generation (“old Generation”)이라는 또 다른 메모리 영역이 있습니다. 이는 많은 가비지 수집을 통해 살아남은 매우 오래 지속되는 개체입니다. 다른 것들과 별도로 보관하는 것이 더 유리합니다. 그리고 Old Generation 영역이 가득 찬 경우에만, 즉 프로그램에 수명이 긴 개체가 너무 많아 메모리가 부족하더라도 완전한 가비지 수집이 수행됩니다. 이는 하나의 메모리 영역뿐만 아니라 일반적으로 Java 시스템에서 생성된 모든 개체를 처리합니다. 당연히 훨씬 더 많은 시간과 자원이 필요합니다. 그래서 수명이 긴 물건은 따로 보관하기로 결정했습니다. 다른 지역의 공간이 부족해지면 소위 '빠른 가비지 수집'이 수행됩니다. 한 영역만 커버하기 때문에 더욱 경제적이고 빠릅니다. 결국 100세 노인을 위한 공간마저 막히게 되자 대대적인 청소 작업이 돌입하게 된다. 따라서 가장 "무거운" 도구는 더 이상 필요하지 않을 때만 어셈블러에서 사용됩니다. 도식적으로 힙 및 정리의 구조는 다음과 같습니다. 가비지 수집기에 대한 추가 정보 - 5
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION