[java] System.gc ()는 언제 뭔가를합니까?

Java에서 가비지 수집이 자동화된다는 것을 알고 있습니다. 그러나 System.gc()코드를 호출 하면 JVM이 해당 시점에서 가비지 수집을 수행할지 여부를 결정할 수 있음을 이해 했습니다. 이것이 정확히 어떻게 작동합니까? JVM은 정확히 어떤 기준 / 매개 변수에서 GC를 수행할지 여부를 결정 System.gc()합니까?

이것을 코드에 넣는 것이 좋은 경우에 대한 예가 있습니까?



답변

실제로는 일반적으로 가비지 콜렉션을 수행하기로 결정합니다. 대답은 실행중인 JVM, 어떤 모드에 있는지, 사용중인 가비지 수집 알고리즘과 같은 많은 요인에 따라 다릅니다.

나는 당신의 코드에서 그것에 의존하지 않을 것입니다. JVM이 OutOfMemoryError를 발생시키려는 경우 System.gc () 호출은이를 중지하지 않습니다. 가비지 컬렉터가 극도로 진행되기 전에 가능한 한 많이 해제하려고하기 때문입니다. 내가 실제로 사용하는 것을 본 유일한 시간은 사용자가 클릭 할 수있는 버튼에 연결된 IDE에 있지만 그다지 유용하지는 않습니다.


답변

System.gc ()를 호출하는 것이 합리적이라고 생각할 수있는 유일한 예는 가능한 메모리 누수를 검색하기 위해 애플리케이션을 프로파일 링 할 때입니다. 프로파일 러는 메모리 스냅 샷을 찍기 직전에이 메서드를 호출한다고 생각합니다.


답변

Java 언어 사양은를 호출 할 때 JVM이 GC를 시작한다고 보장하지 않습니다 System.gc(). 이것이 “그 시점에서 GC를 수행하기로 결정할 수도 있고 결정하지 않을 수도 있습니다”의 이유입니다.

이제 Oracle JVM의 중추 인 OpenJDK 소스 코드 를 살펴보면에 대한 호출 System.gc()이 GC주기를 시작 한다는 것을 알 수 있습니다. J9와 같은 다른 JVM을 사용하는 경우 해당 문서를 확인하여 답을 찾아야합니다. 예를 들어 Azul의 JVM에는 지속적으로 실행되는 가비지 수집기가 있으므로에 대한 호출 System.gc()은 아무 작업도 수행하지 않습니다.

다른 답변은 JConsole 또는 VisualVM에서 GC 시작을 언급합니다. 기본적으로 이러한 도구는 System.gc().

일반적으로 코드에서 가비지 수집주기를 시작하고 싶지 않습니다. 애플리케이션의 의미 체계를 망칠 수 있기 때문입니다. 애플리케이션은 비즈니스 작업을 수행하고 JVM은 메모리 관리를 처리합니다. 이러한 문제를 분리해야합니다 (애플리케이션이 메모리 관리를 수행하도록하지 말고 비즈니스에 집중).

그러나에 대한 호출을 System.gc()이해할 수있는 경우는 거의 없습니다 . 예를 들어 마이크로 벤치 마크를 고려하십시오. 아무도 마이크로 벤치 마크 중간에 GC주기가 발생하기를 원하지 않습니다. 따라서 각 측정 사이에 GC주기를 트리거하여 모든 측정이 빈 힙으로 시작되도록 할 수 있습니다.


답변

Java에서 GC를 제어 할 수 없습니다. VM이 결정합니다. 나는 사례를 통해 실행 적이 System.gc()있다 필요합니다 . 때문에 System.gc()호출이 단순히 VM은 가비지 수집을 할 것을 제안하고 또한 전체 가비지 컬렉션 (다중 세대 힙에 이전 및 새 세대)를 수행 한 후 실제로 발생할 수 있습니다 더 많은 CPU 사이클이 필요 이상으로 소비 될 수 있습니다.

어떤 경우에는 애플리케이션이 무거운 작업이 발생하기 전에 다음 몇 분 동안 유휴 상태가 될 것임을 알 수 있으므로 VM이 지금 전체 수집을 수행하도록 제안하는 것이 합리적 일 수 있습니다. 예를 들어, 응용 프로그램을 시작하는 동안 많은 임시 개체를 초기화 한 직후 (즉, TON의 정보를 캐시했으며 1 분 정도는 많은 활동을하지 않을 것임을 알고 있습니다). Eclipse 시작과 같은 IDE를 생각해보십시오. 초기화에 많은 작업을 수행하므로 아마도 초기화 직후에 전체 gc를 수행하는 것이 좋습니다.


답변

전화 할 경우 매우 조심해야합니다 System.gc(). 이를 호출하면 애플리케이션에 불필요한 성능 문제가 추가 될 수 있으며 실제로 수집을 수행한다고 보장 할 수 없습니다. 실제로 System.gc()java 인수를 통해 명시 적을 비활성화 할 수 있습니다 -XX:+DisableExplicitGC.

가비지 컬렉션에 대한 자세한 내용은 Java HotSpot Garbage Collection 에서 제공하는 문서를 읽어 보는 것이 좋습니다 .


답변

System.gc()VM에 의해 구현되며 구현에 따라 다릅니다. 예를 들어 구현자는 단순히 반환하고 아무것도 할 수 없습니다.

수동 수집을 발행해야하는 경우에 대해 이렇게 할 수있는 유일한 시간은 소규모 컬렉션 ( Map<String,<LinkedList>> 예 : 예를 들어)이 포함 된 대규모 컬렉션을 포기
하고 성능 히트를 시도하고 싶을 때입니다. 하지만 대부분의 경우 걱정할 필요가 없습니다. GC는 대부분의 경우 슬프게도 당신보다 잘 알고 있습니다.


답변

직접 메모리 버퍼를 사용하는 경우 직접 메모리가 부족하더라도 JVM이 GC를 실행하지 않습니다.

전화를 걸고 ByteBuffer.allocateDirect()OutOfMemoryError가 발생하면 GC를 수동으로 트리거 한 후이 호출이 괜찮다는 것을 알 수 있습니다.