>  기사  >  Java  >  Java에서 GC 가비지 수집기의 중요성과 GC와의 상호 작용에 대한 간략한 분석

Java에서 GC 가비지 수집기의 중요성과 GC와의 상호 작용에 대한 간략한 분석

高洛峰
高洛峰원래의
2017-01-17 15:43:34932검색

객체는 new를 사용하여 생성되지만 객체가 차지하는 메모리를 재활용하기 위한 해당 삭제 작업이 없습니다. 객체 사용이 끝나면 객체 참조를 중단합니다. 참조를 다른 객체 또는 null로 변경하거나 메소드에서 반환하여 메소드의 지역 변수가 더 이상 존재하지 않도록 합니다. 변수는 객체를 가리키지 않습니다. 더 이상 참조되지 않는 객체를 가비지라고 하며 이러한 객체를 찾아 재활용하는 과정을 가비지 수집이라고 합니다. o

Java 가상 머신은 참조된 객체가 메모리에 유지되도록 가비지 수집을 사용합니다. 실행 코드의 참조를 통해 접근할 수 없는 객체가 차지하는 저장 공간이 해제됩니다. 이는 강력한 보장입니다. 루트 참조(즉, 실행 코드에서 직접 액세스할 수 있는 참조)에서 시작하는 참조 체인을 따라 개체에 도달할 수 있는 경우 개체는 재활용되지 않습니다.

간단히 말해서 실행 가능한 코드에서 객체에 접근할 수 없을 때 객체가 차지하는 공간을 회수할 수 있습니다. 메모리 공간이 재활용되는지 여부는 가비지 컬렉터에 의해 결정되기 때문에 "can"이라는 단어를 사용합니다. 일반적으로 가비지 컬렉터는 더 많은 메모리 공간이 필요하거나 메모리 오버플로 실행을 방지하기 위해 메모리 공간을 재활용합니다. 하지만 메모리 오버플로 없이 프로그램이 종료되거나 메모리 오버플로에 가깝지 않은 경우에도 프로그램이 종료될 수 있으므로 가비지 수집을 전혀 수행할 필요가 없을 수도 있습니다. 현재 실행되는 모든 메소드에서 모든 변수에 객체에 대한 참조가 포함되어 있지 않고 이러한 변수에서 시작하여 참조 체인을 따라 있는 필드나 배열 요소에서 이 객체에 대한 참조가 발견되지 않으면 객체가 다음과 같다고 말합니다. "접근할 수 없음".

가비지 컬렉션을 사용하면 매달린 참조에 대해 걱정할 필요가 없습니다. 프로그래머가 개체 삭제 시기를 직접 제어할 수 있는 시스템에서 프로그래머는 여전히 다른 개체에서 참조하는 개체를 삭제할 수 있습니다. 프로그래머가 이러한 개체를 삭제하면 삭제된 개체를 계속 참조하고 있는 참조도 삭제됩니다. . 운영 체제에서 할당 가능하다고 간주하지만 실제로는 해제된 메모리 공간을 참조하기 때문에 매달리게 됩니다. 시스템은 이 할당 가능한 공간을 새 개체에 할당할 수 있으므로 원래 공간을 가리키는 참조가 실제로 예상했던 것과 완전히 다른 개체를 얻게 됩니다. 이 경우 프로그램이 이 공간에 저장된 값을 이용하여 자신이 속하지 않는 객체로 동작하게 되면 예측할 수 없는 재난이 발생할 수 있다. 가비지 수집은 여전히 ​​참조되는 모든 개체가 가비지 수집으로 처리되지 않아 해당 개체가 차지하는 공간을 해제할 수 없기 때문에 허상 참조 문제를 해결합니다. 또한 가비지 수집은 동일한 객체를 실수로 여러 번 삭제하는 문제(재난으로 이어질 수 있는 문제)를 해결합니다. 쓰레기 개체를 재활용하는 데는 우리의 개입이 필요하지 않지만 쓰레기 재활용은 특정 시스템 리소스를 차지합니다. 많은 수의 개체를 생성하고 재활용하는 것은 시간이 중요한 애플리케이션에 지장을 줄 수 있으므로 이러한 시스템을 설계할 때 재활용할 쓰레기의 양을 줄이기 위해 생성된 개체 수를 신중하게 처리해야 합니다.

가비지 수집은 메모리에 새 객체를 생성할 공간이 항상 있다는 것을 보장하지 않습니다. 예를 들어, 객체를 계속 생성하여 목록에 넣으면 새 객체를 생성할 공간이 부족하고 참조되지 않은 객체가 없으면 새 객체를 생성할 수 없습니다. 위 목록에 더 이상 필요하지 않은 객체에 대한 참조를 보관하면 메모리 누수가 발생합니다. 가비지 수집은 많은(전부는 아님) 메모리 할당 문제를 해결합니다.

가비지 컬렉터와의 상호작용

Java 언어 자체에는 유휴 객체를 처리하는 명시적인 방법이 없지만 가비지 컬렉터를 직접 호출하여 더 이상 사용되지 않는 객체를 찾을 수 있습니다. . 런타임 클래스와 시스템 클래스의 일부 편리한 메서드를 사용하면 가비지 수집기를 호출하고, 실행할 모든 종료자를 실행하도록 요청하거나, 현재 메모리 상태를 볼 수 있습니다.

 .public void gc Q: 이 메서드는 요청합니다. Java 가상 머신은 더 이상 사용되지 않는 객체를 회수하여 이러한 객체가 차지하는 메모리를 재사용할 수 있도록 에너지를 소비합니다.

.public void runFinalization(): 이 메소드는 Java 가상 머신이 다음 종료자를 실행하는 데 에너지를 소비하도록 요청합니다. 객체는 도달할 수 없는 것으로 확인되었지만 종료자가 아직 실행되지 않았습니다.

 “public long freememory(): 사용 가능한 시스템 메모리의 예상 바이트 수를 반환합니다.

 ·public long total Memory(): 시스템 메모리의 총 바이트 수를 반환합니다.

.public long maxmemoryo: Java 가상 머신에 사용할 수 있는 시스템 메모리의 최대 바이트 수를 반환합니다. 운영 체제에 Java 가상 머신에 대한 메모리 사용량 제한이 없으면 Long MAX-VALUE가 반환됩니다. Java에서는 사용되지 않습니다. 시스템의 최대 메모리를 설정하는 방법 일반적으로 Java 가상 머신은 명령줄이나 기타 구성 옵션을 통해 이 값을 설정합니다.

위 메소드를 호출하려면 정적 메소드 Runtime.getRuntime을 통해 현재 런타임 객체에 대한 참조를 얻어야 합니다. 시스템 클래스는 현재 런타임 개체에서 해당 메서드를 호출하는 정적 gc 및 runFinalization 메서드를 지원합니다. 즉, System.gc() 및 Runtime.getRuntime().gc() 메서드는 동일합니다.

Runtime.gc() 메서드를 호출할 때 가비지 수집기는 수집할 가비지가 없을 수 있고 모든 가비지 수집기가 요청 시 사용 가능한 메모리를 찾을 수 없기 때문에 추가 메모리를 해제하지 못할 수 있습니다. 물건을 재활용하세요. 따라서 가비지 수집기를 호출해도 효과가 없을 수 있습니다. 그러나 특히 가비지 수집 오버헤드가 영향을 미칠 수 있는 시간이 중요한 응용 프로그램에서는 많은 수의 개체를 만들기 전에 Runtime.gc() 메서드를 호출하는 것이 좋습니다. 이를 수행하면 두 가지 잠재적 이점이 있습니다. 첫 번째는 애플리케이션을 실행하기 전에 가능한 한 많은 메모리를 얻을 수 있다는 것이고, 두 번째는 작업 실행 중에 가비지 수집기가 실행될 가능성을 줄일 수 있다는 것입니다. 다음 메소드는 런타임 시 해제될 수 있는 모든 공간을 적극적으로 해제합니다.

public static vo记ful1GC(){
 
Runtime rt=Runtime.getRuntime();
 
long isFree=rt.freeMemory ();
 
long wasFree;
 
do{
 
wasFree=isFree;
 
rt.runFinalization ();
 
rt.gc();
 
isFree二rt.freeMemory();
 
}while (isFree>wasFree);
 
}

이 메소드는 계속해서 runFinalization 및 gc 메소드를 호출하여 freememory 값이 계속 증가합니다. 사용 가능한 메모리 양이 더 이상 증가하지 않으면 이 메서드의 루프가 종료됩니다.

finalize 메소드는 가비지 컬렉터에 의해 비동기적으로 호출되기 때문에 일반적으로 runFinalization 메소드를 호출할 필요가 없습니다. finalize 메서드로 회수할 수 있는 항목의 리소스가 소진된 경우와 같은 일부 경우에는 run-Finalization을 호출하여 최대한 많은 최종화를 강제하는 것이 유용합니다. 그러나 마무리를 기다리는 개체가 이 리소스를 사용하고 있다는 보장은 없으므로 runFinalization이 아무런 영향을 미치지 않을 수 있다는 점을 기억하세요.

fullGc 접근 방식은 대부분의 애플리케이션에 너무 공격적입니다. 가비지 수집을 강제해야 하는 특수한 경우 system.gc 메서드에 대한 단일 호출은 사용 가능한 가비지 중 대부분을 수집하므로 반복 호출은 많은 시스템에서 가비지 수집 속도의 출력을 감소시킵니다. 이러한 반복적인 호출은 비생산적입니다.

Java에서 GC 가비지 컬렉터의 의미와 GC와의 상호 작용에 대한 더 많은 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.