it-swarm-ko.tech

System.gc ()는 언제 작동합니까?

가비지 수집이 Java에서 자동화된다는 것을 알고 있습니다. 그러나 코드에서 System.gc()을 호출하면 JVM이 해당 시점에서 가비지 수집을 수행하거나 결정하지 않을 수 있음을 이해했습니다. 이것이 정확히 어떻게 작동합니까? JVM이 System.gc()을 볼 때 GC를 수행하거나 수행하지 않기로 결정한 기준은 무엇입니까?

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

111
harry

실제로 보통는 가비지 수집을 결정합니다. 대답은 실행중인 JVM, 사용중인 모드 및 사용중인 가비지 수집 알고리즘과 같은 많은 요소에 따라 다릅니다.

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

58
jodonnell

System.gc ()를 호출하는 것이 적절한 곳을 생각할 수있는 유일한 예는 가능한 메모리 누수를 검색하기 위해 응용 프로그램을 프로파일 링하는 경우입니다. 프로파일 러는 메모리 스냅 샷을 찍기 직전 에이 메소드를 호출한다고 생각합니다.

29

Java 언어 사양은 System.gc()을 (를) 호출 할 때 JVM이 GC를 시작한다고 보장하지 않습니다. 이것이 "GC를 수행할지 여부를 결정하는 이유입니다. 그 시점에서 ".

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

다른 대답은 JConsole 또는 VisualVM에서 GC를 시작하는 것에 대한 언급입니다. 기본적으로 이러한 도구는 System.gc()을 원격으로 호출합니다.

일반적으로 코드에서 가비지 콜렉션주기를 시작하지 않으려는 경우가 있습니다. 이는 애플리케이션의 의미를 엉망으로 만들기 때문입니다. 애플리케이션은 비즈니스를 수행하고 JVM은 메모리 관리를 담당합니다. 이러한 우려를 분리하여 유지해야합니다 (응용 프로그램이 일부 메모리 관리를 수행하지 않도록하고 비즈니스에 집중하도록하십시오).

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

24
Pierre Laporte

Java-VM 결정)에서 GC를 제어 할 수 없습니다. System.gc()이 (가) = neededSystem.gc() 호출 때문에 VM 가비지 수집을 수행하고 또한 전체 가비지 수집 (이전 및 새)을 수행한다고 제안합니다. 여러 세대의 힙에서 생성)하면 실제로는 MORE CPU 사이클이 필요 이상으로 소비 될 수 있습니다.

경우에 따라 VM에 전체 컬렉션을 수행하도록 제안하는 것이 좋을 것입니다. 무거운 리프팅이 발생하기 전에 다음 몇 분 동안 응용 프로그램이 유휴 상태가 될 것입니다. 예를 들어, 응용 프로그램을 시작하는 동안 많은 임시 개체를 초기화 한 직후 (예 : 방금 TON의 정보를 캐시했으며 1 분 정도 많은 활동을 얻지 못한다는 것을 알고 있습니다) IDE 이클립스 시작과 같은) 초기화하는 데 많은 도움이되므로 초기화 직후에 그 시점에서 전체 gc를 수행하는 것이 좋습니다.

23
DustinB

System.gc()을 호출하면 매우주의해야합니다. 호출하면 애플리케이션에 불필요한 성능 문제가 추가 될 수 있으며 실제로 콜렉션을 수행한다고 보장되지는 않습니다. Java 인수 -XX:+DisableExplicitGC를 통해 명시 적 System.gc()을 비활성화 할 수 있습니다.

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

17
David Schlosnagle

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

수동 수집을 수행 할 때,이를 수행 할 수있는 유일한 시간은 소규모 컬렉션 (예 : Map<String,<LinkedList>>)이 포함 된 대규모 컬렉션을 포기하고 시도하고 싶을 때뿐입니다. 퍼포먼스를 치면 대부분의 경우 걱정할 필요가 없습니다. GC는 대부분 슬프게도 당신보다 더 잘 알고 있습니다.

10
Patrick

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

ByteBuffer.allocateDirect()을 호출하고 OutOfMemoryError가 발생하면 GC를 수동으로 트리거 한 후이 호출이 정상임을 알 수 있습니다.

8
Peter Lawrey

대부분의 JVM은 -C :: DiableExplicitGC 및 -XX : + ExplicitGCInvokesConcurrent 스위치에 따라 GC를 시작합니다. 그러나 나중에 더 나은 구현을 위해 사양이 잘 정의되지 않았습니다.

사양을 명확히해야합니다. 버그 # 6668279 : (사양) System.gc ()는 사용을 권장하지 않으며 동작을 보증하지 않음을 나타내야합니다

내부적으로 gc 메소드는 RMI 및 NIO에서 사용되며 동기 실행이 필요합니다. 현재 논의 중입니다.

버그 # 5025281 : System.gc ()가 동시 (전 세계가 아닌) 전체 컬렉션을 트리거하도록 허용

5
eckes

Garbage CollectionJava에 적합합니다. 우리가 Java 데스크톱/노트북/서버에서 코딩 된 소프트웨어를 실행하는 경우) System.gc() 또는 JavaRuntime.getRuntime().gc().

이러한 통화 중 아무 것도 수행 할 수있는 것은 아닙니다. jvm이 가비지 콜렉터를 실행하도록 제안합니다. GC 실행 여부에 관계없이 JVM입니다. 짧은 대답 : 우리는 그것이 언제 실행되는지 알 수 없습니다. 더 긴 대답 : JVM은 시간이 있으면 gc를 실행합니다.

안드로이드에도 동일하게 적용됩니다. 그러나 이로 인해 시스템 속도가 느려질 수 있습니다.

2
Naveen

일반적으로 VM는 OutOfMemoryException을 발생시키기 전에 가비지 수집을 자동으로 수행하므로 명시적인 호출을 추가하면 성능 저하가 더 이른 시점으로 이동한다는 점을 제외하고는 도움이되지 않습니다.

그러나 관련성이있는 경우가 발생했다고 생각합니다. 그래도 효과가 있는지 테스트하지 않았으므로 확실하지 않습니다.

파일을 메모리 매핑 할 때 충분한 메모리 블록을 사용할 수 없으면 map () 호출에서 IOException이 발생한다고 생각합니다. map () 파일 바로 앞에있는 가비지 수집이이를 방지하는 데 도움이 될 수 있습니다. 어떻게 생각해?

2
Vashek

우리는 절대 가비지 콜렉션을 강요 할 수 없습니다. System.gc는 가비지 수집을 위해 vm 만 제안하지만 실제로 메커니즘이 실행되는 시간은 아무도 모르지만 JSR 사양에 명시되어 있습니다.

2
lwpro2

다양한 가비지 수집 설정을 테스트하는 데 많은 시간이 걸리지 만, 위에서 언급했듯이 일반적으로 그렇게하는 것은 유용하지 않습니다.

현재 메모리 제한 환경과 상대적으로 많은 양의 데이터가 포함 된 프로젝트를 진행하고 있습니다. 환경을 한계로 밀어 붙일 수있는 몇 개의 큰 데이터가 있으며 메모리 사용량을 줄일 수 있었지만 이론 상으로는 제대로 작동해야하지만 힙 공간 오류가 계속 발생합니다. 자세한 GC 옵션은 가비지 수집을 시도했지만 아무 소용이 없다는 것을 보여주었습니다. 디버거에서 System.gc ()를 수행 할 수 있으며 충분한 메모리가 충분할 것입니다.

결과적으로 내 응용 프로그램이 System.gc ()를 호출하는 유일한 시간은 데이터 처리에 필요한 큰 버퍼가 할당 될 코드 세그먼트를 입력하려고 할 때이며 사용 가능한 여유 메모리에 대한 테스트는 내가 아닌 것으로 나타냅니다 그것을 보장합니다. 특히, 정적 데이터가 300MB 이상을 차지하는 1GB 환경을보고 있는데, 처리되는 데이터가 100-200MB 이상인 경우를 제외하고는 대부분의 비 정적 데이터가 실행 관련입니다. 소스. 자동 데이터 변환 프로세스의 일부이므로 데이터는 장기적으로 비교적 짧은 기간 동안 존재합니다.

불행하게도 가비지 콜렉터를 조정하기위한 다양한 옵션에 대한 정보를 사용할 수 있지만, 이는 일반적으로 실험적인 프로세스이며 이러한 특정 상황을 처리하는 방법을 이해하는 데 필요한 하위 레벨 특성은 쉽게 얻을 수 없습니다.

내가 말한 모든 것은 System.gc ()를 사용하더라도 명령 줄 매개 변수를 사용하여 계속 조정하고 응용 프로그램의 전체 처리 시간을 상대적으로 상당히 향상 시켰습니다. 더 큰 데이터 블록으로 작업하여 발생하는 걸림돌. 즉, System.gc ()는 매우 신뢰할 수없는 도구입니다. 사용 방법에주의하지 않으면 더 자주 작동하지 않기를 바랍니다.

2
Kyune

한마디로 :

매개 변수는 VM 종속적입니다.

사용 예-런타임/프로덕션 앱용으로는 생각할 수 없지만 호출과 같은 일부 프로파일 링 하니스에서는 실행하는 것이 유용합니다.

// test run #1
test();
for (int i=0; i<10; i++) { 
// calling repeatedly to increase chances of a clean-up
  System.gc(); 
}
// test run #2
test();
1
mataal

System.gc()이 호출되는지 알고 싶다면 JVM이 가비지 콜렉션을 수행 할 때 새로운 Java 7 업데이트 4 알림 수신)를 사용하면됩니다.

GarbageCollectorMXBean 클래스가 Java 7 업데이트 4에서 소개되었지만 릴리스 노트에서 찾을 수 없기 때문에 100 % 확실하지는 않지만 100 % 확실하지는 않습니다. javaperformancetuning . com 사이트의 정보

1
Shervin Asgari

Java Bruce Eckel의 Thinking in Thinking)에 따르면 명시 적 System.gc () 호출의 사용 사례는- 최종 방법.

0
Asterisk

명시 적 GC를 실행하는 것이 좋은 경우 특정 예를 생각할 수 없습니다.

일반적으로 명시 적 GC를 실행하면 전체 GC가 전체 콜렉션을 트리거하므로 모든 오브젝트를 통과 할 때 시간이 훨씬 오래 걸리기 때문에 실제로 GY보다 더 많은 피해를 줄 수 있습니다. 이 명시 적 gc가 반복적으로 호출되면 전체 GC를 실행하는 데 많은 시간이 소비되므로 응용 프로그램이 느려질 수 있습니다.

또는 힙 분석기로 힙을 처리하고 라이브러리 컴포넌트가 명시 적 GC를 호출하는 것으로 의심되는 경우 JVM 매개 변수에 gc = -XX : + DisableExplicitGC를 추가하여이를 끌 수 있습니다.

0
zxcv

system.gc가 작동하는 동안 세상을 막을 것입니다 : 모든 응답이 중지되어 가비지 수집기가 모든 객체를 스캔하여 삭제 해야하는지 확인할 수 있습니다. 응용 프로그램이 웹 프로젝트 인 경우 gc가 완료 될 때까지 모든 요청이 중지되어 웹 프로젝트가 monent에서 작동하지 않을 수 있습니다.

0
fleture