저는 Java를 처음 접했고 Java의 가비지 수집기에 대해 혼란 스럽습니다. 실제로 무엇을하고 언제 작동합니까? Java에서 가비지 수집기의 일부 속성을 설명하십시오.
저는 Java를 처음 접했고 Java의 가비지 수집기에 대해 혼란 스럽습니다. 실제로 무엇을하고 언제 작동합니까? Java에서 가비지 수집기의 일부 속성을 설명하십시오.
답변:
가비지 컬렉터는 온 실행되는 프로그램입니다 자바 가상 머신 더 이상 자바 응용 프로그램에서 사용되지 않는 객체를 제거한다. 자동 메모리 관리 의 한 형태입니다 .
일반적인 Java 애플리케이션이 실행 중일 때 Strings 및 Files 와 같은 새 객체를 생성 하지만 일정 시간이 지나면 해당 객체는 더 이상 사용되지 않습니다. 예를 들어, 다음 코드를 살펴보십시오.
for (File f : files) {
String s = f.getName();
}
위의 코드에서는 루프가 String s반복 될 때마다 생성됩니다 for. 이것은 모든 반복에서 String객체 를 만들기 위해 약간의 메모리가 할당된다는 것을 의미 합니다.
코드로 돌아 가면 단일 반복이 실행되면 다음 반복 String에서 이전 반복에서 생성 된 객체가 더 이상 사용되지 않음을 알 수 있습니다. 이제 해당 객체는 "가비지"로 간주됩니다.
결국 우리는 많은 쓰레기를 얻기 시작할 것이고 더 이상 사용되지 않는 객체에 메모리가 사용될 것입니다. 이것이 계속되면 결국 자바 가상 머신은 새로운 객체를 만들기위한 공간이 부족해질 것입니다.
그것이 가비지 수집기가 개입하는 곳입니다.
가비지 수집기는 더 이상 사용되지 않는 개체를 찾아 제거하여 다른 새 개체가 해당 메모리를 사용할 수 있도록 메모리를 확보합니다.
자바에서 메모리 관리는 가비지 컬렉터에 의해 처리되어 있지만, C와 같은 다른 언어로, 하나의 요구는 다음과 같은 자신의 사용 기능에 메모리 관리를 수행 malloc하고free . 메모리 관리 는 실수하기 쉬운 것들 중 하나이며, 메모리 누수 ( 메모리가 더 이상 사용되지 않을 때 메모리가 회수되지 않는 곳)로 이어질 수 있습니다 .
가비지 수집과 같은 자동 메모리 관리 체계를 사용하면 프로그래머가 메모리 관리 문제에 대해 그다지 걱정할 필요가 없으므로 개발해야하는 응용 프로그램 개발에 더 집중할 수 있습니다.
프로그램에서 더 이상 사용하지 않는 개체에 할당 된 메모리를 해제하므로 이름이 "가비지"입니다. 예를 들면 :
public static Object otherMethod(Object obj) {
return new Object();
}
public static void main(String[] args) {
Object myObj = new Object();
myObj = otherMethod(myObj);
// ... more code ...
}
나는 이것이 극도로 인위적이라는 것을 알고 있지만, 여기에서 생성 otherMethod()된 원본 Object은 도달 할 수 없게됩니다. 이것이 가비지 수집을받는 "쓰레기"입니다.
Java에서 GC는 자동으로 실행되지만 다음을 사용하여 명시 적으로 호출 할 수도 있습니다. System.gc() 및 시도 의 주요 가비지 수집을 강제로. Pascal Thivent가 지적했듯이, 당신은 정말로 이것을 할 필요 가 없으며 그것은 좋은 것보다 더 많은 해를 끼칠 수 있습니다 ( 이 질문 참조 ).
자세한 내용은 가비지 컬렉션 에 대한 wikipedia 항목을 참조하십시오. 및 튜닝 가비지 컬렉션 (Oracle 제공)을 참조하십시오.
System.gc()는 GC를 강제로 실행하지 않습니다.
myObj호출 otherMethod이 발생 하기 전에 GC가 파괴하는 것은 완벽하게 유효 myObj합니다.
System.gc(). GC를 갖는 요점은 그렇게 할 필요가 없다는 것입니다.
객체는 라이브 스레드 또는 정적 참조에서 도달 할 수없는 경우 가비지 수집 또는 GC에 적합합니다.
즉, 모든 참조가 null 인 경우 개체가 가비지 수집 대상이된다고 말할 수 있습니다. 순환 종속성은 참조로 계산되지 않으므로 개체 A에 개체 B에 대한 참조가 있고 개체 B에 개체 A에 대한 참조가 있고 다른 라이브 참조가없는 경우 개체 A와 B 모두 가비지 수집 대상이됩니다.
가비지 수집을위한 힙 생성-
자바 객체가 만들어집니다 Heap및 Heap자바의 가비지 컬렉션을 위해서 세 부분 또는 세대로 구분되며, 이들은라고 같은 영 (새로운) 세대, 종신 (구) 생성 및 페름 지역 힙.
New Generation 은 Eden 공간, Survivor 1 및 Survivor 2 공간으로 알려진 세 부분으로 더 나뉩니다. 객체가 힙에서 처음 생성 될 때 Eden 공간 내부의 새로운 세대에서 생성되고 객체가 살아남 으면 후속 마이너 가비지 컬렉션 이후에 생성 됩니다.
Java Heap의 Perm 공간 은 JVM이 클래스 및 메소드, 문자열 풀 및 클래스 레벨 세부 사항에 대한 메타 데이터를 저장하는 곳입니다.
자세한 내용은 여기를 참조하십시오 : 가비지 컬렉션
System.gc()또는 Runtime.gc()메소드를 사용하여 요청할 수 있지만 JVM이 가비지 수집을 실행하도록 강제 할 수는 없습니다 .
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
Mark and Sweep 알고리즘-
이것은 가비지 수집에서 가장 많이 사용되는 알고리즘 중 하나입니다. 모든 가비지 수집 알고리즘은 두 가지 기본 작업을 수행해야합니다. 하나는 도달 할 수없는 모든 개체를 감지 할 수 있어야하고 두 번째는 가비지 개체가 사용하는 힙 공간을 회수하고 해당 공간을 프로그램에서 다시 사용할 수 있도록해야한다는 것입니다.
위의 작업은 Mark 및 Sweep 알고리즘에 의해 두 단계로 수행됩니다.
자세한 내용은 여기를 참조하십시오 -Mark and Sweep 알고리즘
가비지 콜렉터는 참조되지 않는 객체가 메모리에서 해제되도록하는 JRE의 일부입니다.
일반적으로 앱의 메모리가 부족할 때 실행됩니다. AFAIK는 객체와 분리 된 객체 사이의 링크를 나타내는 그래프를 보유하고 있습니다.
성능을 절약하기 위해 세대로 그룹화 된 현재 객체는 GC가 객체를 스캔하고 여전히 참조되고 있음을 발견 할 때마다 1 씩 증가 된 세대 수 (최대 최대 값, 3 또는 4로 생각), 새로운 세대가 먼저 스캔됩니다. (메모리의 개체가 가장 짧을수록 더 이상 필요하지 않음) GC가 실행될 때마다 모든 개체가 스캔되는 것은 아닙니다. 자세한 내용은 이것을
읽으십시오 .
가비지 수집기를 사용하면 컴퓨터가 무한 메모리가있는 컴퓨터를 시뮬레이션 할 수 있습니다. 나머지는 단지 메커니즘입니다.
코드에서 더 이상 메모리 청크에 액세스 할 수없는시기를 감지하고 해당 청크를 무료 저장소로 반환하여이를 수행합니다.
편집 : 예, 링크는 C # 용이지만 C #과 Java는 이와 관련하여 동일합니다.
많은 사람들은 가비지 수집이 죽은 개체를 수집하고 폐기한다고 생각합니다.
실제로 Java 가비지 콜렉션은 그 반대입니다! 살아있는 물체는 추적되고 다른 모든 것은 쓰레기로 지정됩니다.
개체가 더 이상 사용되지 않으면 가비지 수집기는 기본 메모리를 회수하고 향후 개체 할당을 위해 다시 사용합니다. 즉, 명시적인 삭제가 없으며 운영 체제에 메모리가 다시 제공되지 않습니다. 더 이상 사용되지 않는 개체를 확인하기 위해 JVM은 마크 앤 스윕 알고리즘이라고하는 것을 간헐적으로 실행합니다.
자세한 내용은 http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx 를 확인하십시오.
프로그래머가 아닌 사람도 이해할 수있는 가장 간단한 용어로 말하자면, 프로그램이 데이터를 처리 할 때 해당 데이터에 대한 중간 데이터 및 저장 공간 (변수, 배열, 특정 개체 메타 데이터 등)을 생성합니다.
이러한 개체가 함수 전체에서 또는 특정 크기 이상으로 액세스되면 중앙 힙에서 할당됩니다. 그런 다음 더 이상 필요하지 않으면 정리해야합니다.
이것이 어떻게 작동하는지에 대한 아주 좋은 기사가 온라인에 있으므로, 아주 기본적인 정의 만 다룰 것입니다.
GC는 기본적으로이 정리를 수행하는 기능입니다. 이렇게하려면 활성 개체에서 참조하지 않는 테이블 항목을 지우고 메모리를 복사하고 압축하는 것보다 개체를 효과적으로 삭제합니다. 이것보다 조금 더 복잡하지만 아이디어를 얻습니다.
큰 문제는이 프로세스가 발생하기 위해 일시적으로 전체 Java VM을 중지해야하는 경우가 많고이 전체 프로세스가 매우 프로세서 및 메모리 대역폭을 많이 사용한다는 점입니다. GC의 다양한 옵션과 각 옵션에 대한 조정 옵션은 이러한 다양한 문제와 전체 GC 프로세스의 균형을 맞추기 위해 설계되었습니다.
Java (및 기타 언어 / 플랫폼 포함)의 가비지 수집은 Java 런타임 환경 (JRE)이 더 이상 필요하지 않은 Java 객체의 메모리를 재사용하는 방법입니다. 간단히 말해서 JRE가 처음 시작될 때 운영 체제 (O / S)에 특정 양의 메모리를 요청합니다. JRE가 응용 프로그램을 실행할 때 해당 메모리를 사용합니다. 애플리케이션이 해당 메모리를 사용하여 완료되면 JRE의 "Garbage Collector"가 함께 제공되어 기존 애플리케이션의 다른 부분에서 사용할 수 있도록 해당 메모리를 회수합니다. JRE의 "Garbage Collector"는 항상 실행중인 백그라운드 작업이며 시스템이 가비지 실행을 위해 유휴 상태 일 때 시간을 선택하려고합니다.
현실 세계의 비유는 여러분의 집에 와서 여러분의 재활용 쓰레기를 수거하는 쓰레기 수거 자 들일 것입니다. 결국 여러분 자신과 다른 사람들이 다른 방식으로 재사용하게됩니다.
가비지 수집기는 참조 횟수 관리자로 볼 수 있습니다. 객체가 생성되고 참조가 변수에 저장되면 참조 횟수가 1 씩 증가합니다. 해당 변수가 NULL로 할당 된 경우 실행 과정에서. 해당 개체에 대한 참조 횟수가 감소합니다. 따라서 객체의 현재 참조 횟수는 0입니다. 이제 가비지 수집기가 실행되면 참조 횟수가 0 인 객체를 확인하고 할당 된 리소스를 해제합니다.
가비지 수집기 호출은 가비지 수집 정책에 의해 제어됩니다.
여기에서 데이터를 얻을 수 있습니다. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
가비지 수집기는 jvm의 구성 요소입니다.
CPU가 풀릴 때 쓰레기를 수집하는 데 사용됩니다.
여기서 쓰레기는 메인 프로그램의 백그라운드에서 실행되는 미사용 객체를 의미합니다.
메인 프로그램의 상태를 모니터링합니다.
자동 가비지 수집은 힙 메모리를 살펴보고 사용중인 개체와 사용하지 않는 개체를 식별하고 사용하지 않는 개체를 삭제하는 프로세스입니다. 사용중인 개체 또는 참조 된 개체는 프로그램의 일부가 여전히 해당 개체에 대한 포인터를 유지하고 있음을 의미합니다. 사용하지 않는 개체 또는 참조되지 않은 개체는 더 이상 프로그램의 어떤 부분에서도 참조되지 않습니다. 따라서 참조되지 않은 개체가 사용하는 메모리를 회수 할 수 있습니다.
C와 같은 프로그래밍 언어에서 메모리 할당 및 할당 해제는 수동 프로세스입니다. Java에서 메모리 할당 해제 프로세스는 가비지 수집기에 의해 자동으로 처리됩니다. 더 나은 이해를 위해 링크를 확인하십시오. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
가비지 콜렉션의 기본 원칙은 나중에 액세스 할 수없는 프로그램에서 데이터 오브젝트를 찾고 해당 오브젝트가 사용하는 자원을 회수하는 것입니다. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
장점
1) 여전히 포인터가있는 동안 메모리 조각이 해제되고 해당 포인터 중 하나가 역 참조 될 때 발생하는 버그로부터 저장합니다. https://en.wikipedia.org/wiki/Dangling_pointer
2) 프로그램이 이미 해제되었고 아마도 이미 다시 할당 된 메모리 영역을 해제하려고 할 때 발생하는 이중 해제 버그.
3) 특정 종류의 메모리 누수를 방지합니다. 프로그램이 도달 할 수 없게 된 개체가 차지하는 메모리를 해제하지 못하여 메모리 고갈로 이어질 수 있습니다.
단점
1) 추가 리소스 소비, 성능 영향, 프로그램 실행 중단 가능성, 수동 리소스 관리와의 비 호환성. 가비지 콜렉션은 프로그래머가 이미이 정보를 알고있을지라도 확보 할 메모리를 결정하는 데 컴퓨팅 자원을 소비합니다.
2) 가비지가 실제로 수집되는 순간은 예측할 수 없어 세션 전체에 흩어져있는 중단 (이동 / 해제 메모리 해제)이 발생할 수 있습니다. 실시간 환경, 트랜잭션 처리 또는 대화 형 프로그램에서는 예측할 수없는 중단이 허용되지 않을 수 있습니다.
Oracle 자습서 http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
가비지 수집은 사용중인 개체와 사용하지 않는 개체를 식별하고 사용하지 않는 개체를 삭제하는 프로세스입니다.
C, C ++와 같은 프로그래밍 언어에서 메모리 할당 및 해제는 수동 프로세스입니다.
int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory
프로세스의 첫 번째 단계는 마킹이라고합니다. 여기에서 가비지 수집기가 사용중인 메모리와 그렇지 않은 메모리를 식별합니다.
2a 단계. 일반 삭제는 참조되지 않은 개체를 제거하고 참조 된 개체와 여유 공간에 대한 포인터를 남깁니다.
성능을 향상시키기 위해 참조되지 않은 개체를 삭제하고 나머지 참조 된 개체도 압축하려고합니다. 참조 된 객체를 함께 유지하기를 원하므로 새 메모리를 할당하는 것이 더 빠릅니다.
앞서 언급했듯이 JVM의 모든 개체를 표시하고 압축하는 것은 비효율적입니다. 점점 더 많은 개체가 할당됨에 따라 개체 목록이 증가하고 증가하여 가비지 수집 시간이 길어집니다.
이 튜토리얼을 계속 읽으면 GC가이 문제를 어떻게 해결하는지 알게 될 것입니다.
간단히 말해, 힙에는 수명 이 짧은 개체를 위한 YoungGeneration , 장기간 개체를위한 OldGeneration , 그리고 애플리케이션 수명 동안 존재하는 개체 (예 : 클래스, 라이브러리)에 대한 PermanentGeneration의 세 영역이 있습니다.
개체는 new 연산자에 의해 동적으로 할당되므로 이러한 개체가 어떻게 파괴되고 얼마나 바쁜 메모리가 해제되는지 물어볼 수 있습니다. C ++와 같은 다른 언어에서는 delete 연산자에 의해 동적으로 수동 할당 된 개체를 해제해야합니다. Java에는 다른 접근 방식이 있습니다. 자동으로 할당 해제를 처리합니다. 이 기술을 가비지 수집이라고 합니다.
다음과 같이 작동합니다. 객체에 대한 참조가 없으면이 객체가 더 이상 필요하지 않다고 가정하고 객체가 차지하는 메모리를 검색 할 수 있습니다. C ++ 에서처럼 명시 적으로 객체를 삭제할 필요는 없습니다. 가비지 수집은 프로그램 실행 중에 산발적으로 발생합니다. 더 이상 사용되지 않는 하나 이상의 개체가 있기 때문에 단순히 발생하지 않습니다. 또한 여러 Java 런타임 구현에는 가비지 수집에 대한 접근 방식이 다르지만 대부분의 프로그래머는 프로그램을 작성할 때 이에 대해 걱정할 필요가 없습니다.
자동 가비지 콜렉션은 JVM이 궁극적으로 실행중인 프로그램을위한 공간을 확보하기 위해 메모리에서 특정 데이터 포인트를 제거하거나 유지하는 프로세스입니다. 메모리는 먼저 GC (가비지 수집기)가 작업을 수행하는 힙 메모리로 전송 된 다음 종료되거나 유지되도록 결정됩니다. Java는 프로그래머가 항상 신뢰할 수있는 것은 아니라고 가정하므로 필요하지 않은 항목을 종료합니다.