간단히 말해서
마무리 작업은 가비지 수집기에서 처리하는 간단한 문제가 아닙니다. 참조 카운팅 GC와 함께 사용하기는 쉽지만이 GC 제품군은 종종 불완전하므로 일부 객체와 구조의 파괴 및 종료를 명시 적으로 트리거하여 메모리 누수를 보완해야합니다. 가비지 수집기를 추적하는 것이 훨씬 효과적이지만 사용되지 않은 메모리를 식별하는 것보다 시간과 공간 및 복잡성이 큰 복잡한 관리를 요구하는 것과 달리 마무리 및 파괴 할 객체를 식별하기가 훨씬 어렵습니다. 구현.
소개
가비지 수집 언어가 설명에 표시된 것처럼 가비지 수집 프로세스 내에서 파괴 / 완료를 자동으로 처리하지 않는 이유는 무엇입니까?
이러한 언어가 메모리를 관리 할 가치가있는 유일한 리소스로 간주하는 것은 매우 부족합니다. 소켓, 파일 핸들, 응용 프로그램 상태는 어떻습니까?
kdbanman의 답변에 동의하지 않습니다 . 사실은 참조 카운트에 대해 매우 치우 치지 만 대부분 정확하다고 말했지만, 그들이 문제에 대해 불만을 제기 한 상황을 제대로 설명하지는 않습니다.
나는 그 대답에서 발전된 용어가 큰 문제라고 생각하지 않으며, 혼동을 일으킬 가능성이 더 높습니다. 실제로, 제시된 바와 같이, 용어는 대부분 절차가 수행되는 것이 아니라 절차가 활성화되는 방식에 의해 결정된다. 요점은 모든 경우에 더 이상 정리 프로세스에서 더 이상 필요하지 않은 개체를 마무리하고 사용중인 모든 리소스를 해제해야한다는 것입니다. 메모리는 그 중 하나 일뿐입니다. 이상적으로는 가비지 수집기를 사용하여 개체를 더 이상 사용하지 않을 때 모든 작업을 자동으로 수행해야합니다. 실제로, GC가 없거나 결함이있을 수 있으며, 이는 마무리 및 교정 프로그램에 의한 명시 적 트리거링에 의해 보상됩니다.
프로그램에 의한 명시 적 심사는 여전히 사용중인 객체가 명시 적으로 종료 될 때 프로그래밍 오류를 분석하기가 어렵 기 때문에 문제가됩니다.
따라서 자동 가비지 수집을 사용하여 리소스를 회수하는 것이 훨씬 좋습니다. 그러나 두 가지 문제가 있습니다.
일부 가비지 수집 기술은 리소스 누수를 허용하는 메모리 누수를 허용합니다. 이것은 참조 카운팅 GC로 잘 알려져 있지만,주의하지 않고 일부 데이터 조직을 사용할 때 다른 GC 기술에서 나타날 수 있습니다 (여기서는 설명하지 않음).
GC 기술은 더 이상 사용되지 않는 메모리 리소스를 식별하는 데 능숙 할 수 있지만 여기에 포함 된 객체를 마무리하는 것은 간단하지 않을 수 있으며 이러한 객체가 사용하는 다른 리소스를 회수하는 문제를 복잡하게 만드는 경우가 많으며 이는 종종 마무리의 목적입니다.
마지막으로, 종종 잊어 버린 중요한 점은 적절한 후크가 제공되고 GC주기의 비용이 가치가 있다고 생각되면 메모리 부족뿐만 아니라 GC주기가 트리거 될 수 있다는 것입니다. 따라서 어떤 종류의 자원이 없어지면 일부 자원을 확보하기 위해 GC를 시작하는 것이 좋습니다.
참조 카운트 가비지 수집기
참조 카운트는 약한 가비지 수집 기술로 사이클을 제대로 처리하지 못합니다. 쓸모없는 구조를 파괴하고 메모리를 되 찾는 데 약하기 때문에 다른 리소스를 되 찾는 데 실제로 약한 것입니다. 그러나 참조 횟수 GC는 참조 횟수가 0으로 내려갈 때 구조를 회수하므로 주소를 정적으로 또는 유형과 함께 알고 있기 때문에 파이널 라이저는 참조 카운트 가비지 수집기 (GC)와 함께 가장 쉽게 사용할 수 있습니다. 또는 동적으로. 따라서 적절한 종료자를 적용하고 모든 지정된 객체에 대해 프로세스를 재귀 적으로 호출 한 후 (마무리 절차를 통해) 메모리를 정확하게 회수 할 수 있습니다.
간단히 말해서, Ref Counting GC를 사용하면 최종화를 쉽게 구현할 수 있지만 실제로 원형 구조로 인해 GC의 "불완전 성"으로 인해 메모리 교정이 겪는 것과 정확히 동일하게됩니다. 다시 말해, 참조 카운트를 사용 하면 소켓, 파일 핸들 등과 같은 다른 리소스만큼 메모리가 정확하게 관리되지 않습니다 .
실제로 Ref Count GC가 루핑 구조 (일반적으로)를 되 찾을 수없는 것은 메모리 누수로 보일 수 있습니다 . 모든 GC가 메모리 누수를 피할 것으로 기대할 수는 없습니다. GC 알고리즘 및 동적으로 사용 가능한 유형 구조 정보 (예 : 보수적 GC )에 따라 다릅니다
.
가비지 수집기 추적
이러한 누수가없는보다 강력한 GC 제품군은 잘 식별 된 루트 포인터에서 시작하여 메모리의 실제 부분을 탐색하는 추적 제품군 입니다. 이 추적 프로세스에서 방문하지 않은 메모리의 모든 부분 (실제로는 여러 가지 방법으로 분해 할 수 있지만 단순화해야 함)은 메모리의 사용되지 않은 부분이므로 1 을 회수 할 수 있습니다 . 이러한 수집기는 프로그램이 수행하는 방식에 관계없이 더 이상 프로그램에서 액세스 할 수없는 모든 메모리 부분을 회수합니다. 그것은 원형 구조를 되찾고, 더 진보 된 GC는이 패러다임의 변형을 기반으로하며 때로는 고도로 정교합니다. 경우에 따라 참조 횟수와 결합하여 약점을 보완 할 수 있습니다.
문제는 당신의 진술이 (질문의 끝에서) 있다는 것입니다.
자동 가비지 콜렉션을 제공하는 언어는 오브젝트가 더 이상 사용되지 않을 때 100 % 확실하게 알기 때문에 오브젝트 파괴 / 완료를 지원하는 주요 후보로 보입니다.
콜렉터 추적에 기술적으로 올바르지 않습니다 .
100 % 확실성으로 알려진 것은 더 이상 사용되지 않는 메모리 부분입니다 . 더 정확하게 는 프로그램의 논리에 따라 더 이상 사용할 수없는 일부 부분이 여전히 프로그램에 쓸모없는 포인터가있는 경우 여전히 사용중인 것으로 간주되기 때문에 더 이상 액세스 할 수 없다고 말해야합니다 그러나 현재 사용되지 않는 메모리 부분에 사용되지 않은 개체 가 저장되어 있는지 확인하려면 추가 처리와 적절한 구조가 필요합니다 . 프로그램이 더 이상 메모리의 이러한 부분에 연결되어 있지 않기 때문에 프로그램에서 알려진 내용을 확인할 수 없습니다.
따라서 가비지 콜렉션을 통과 한 후에는 더 이상 사용하지 않는 객체를 포함하는 메모리 조각이 남지만 올바른 마무리를 적용하기 위해 이러한 객체가 무엇인지 알 수있는 방법은 없습니다. 또한 추적 수집기가 마크 앤 스윕 유형 인 경우 일부 조각에 이전 GC 패스에서 이미 마무리되었지만 조각화 이유로 사용되지 않은 개체가 포함되어있을 수 있습니다. 그러나 이것은 확장 된 명시 적 타이핑을 사용하여 처리 할 수 있습니다.
간단한 수집기는 추가 메모리없이 이러한 메모리 조각을 회수하기 만하지만, 마무리에는 사용되지 않은 메모리를 탐색하고 포함 된 개체를 식별하고 마무리 절차를 적용하기위한 특정 단계가 필요합니다. 그러나 그러한 탐구에는 거기에 저장된 객체의 유형을 결정해야하며, 적절한 결정을 적용하려면 유형 결정도 필요합니다.
따라서 다양한 기술로 GC 시간에 추가 비용 (추가 패스)과 추가 메모리 비용으로 해당 유형 정보를 제공 할 수 있습니다. 시간과 공간의 오버 헤드가 모든 개체와 관련 될 수있는 반면, 종종 몇 가지 개체 만 마무리하기를 원하므로 이러한 비용이 상당 할 수 있습니다.
또 다른 요점은 시간 및 공간 오버 헤드가 GC 실행뿐만 아니라 프로그램 코드 실행과 관련 될 수 있다는 것입니다.
나는 당신이 열거 한 많은 언어들의 세부 사항을 알지 못하기 때문에 특정 문제를 지적하면서 더 정확한 대답을 줄 수 없습니다. C의 경우 타이핑은 매우 어려운 문제이며 보수적 인 수집가의 개발로 이어집니다. 내 생각 엔 이것이 C ++에도 영향을 미치지 만 C ++에 대한 전문가는 아닙니다. 이는 보수적 GC에 대한 많은 연구를 수행 한 Hans Boehm에 의해 확인 된 것으로 보인다 . 보수적 GC는 데이터에 대한 정확한 유형 정보가 없기 때문에 사용되지 않은 모든 메모리를 체계적으로 회수 할 수 없습니다. 같은 이유로 마무리 절차를 체계적으로 적용 할 수 없습니다.
따라서 일부 언어에서 알 수 있듯이 원하는 것을 할 수 있습니다. 그러나 그것은 무료로 오지 않습니다. 언어 및 구현에 따라 기능을 사용하지 않더라도 비용이 발생할 수 있습니다. 이러한 문제를 해결하기 위해 다양한 기술과 장단점이 고려 될 수 있지만 이는 합당한 규모의 답변 범위를 벗어납니다.
1-이것은 추적 콜렉션 (복사 및 표시 및 스위프 GC를 모두 포함)의 추상 프리젠 테이션이며, 추적 콜렉터의 유형에 따라 상황이 다르며, 복사 또는 표시 여부에 따라 메모리의 사용되지 않은 부분 탐색이 다릅니다. 스윕이 사용됩니다.
finalize
/destroy
거짓말인가? 그것이 실행될 것이라는 보장은 없습니다. 그리고, (자동 가비지 콜렉션이 제공된시기)를 알지 못하고 필요한 컨텍스트가 여전히 존재하는 경우 (이미 수집 된 상태 일 수 있음). 따라서 다른 방법으로 일관성있는 상태를 유지하는 것이 더 안전하며 프로그래머가 강제로 수행하도록 할 수 있습니다.