>  기사  >  Java  >  Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

WBOY
WBOY앞으로
2023-05-16 12:31:111472검색

문제 시스템

일일 검사 결과 빈번한 Full gc가 발견되었습니다

응용 프로그램 라인에 현상이 나타났습니다

자주 전체 gc가 응용 프로그램 라인에 나타났습니다


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

문제 해결 프로세스

dump 분석

Pull 덤프 파일: Interlude : 덤프 시 live를 지정하면 jvm은 덤프 전에 full gc를 수행하고 dump full gc가 gc 로그에 인쇄됩니다. 비메모리 누수로 인한 온라인 비정상적인 메모리 상태에 대한 이러한 종류의 문제 해결은 불편을 초래할 수 있습니다. 우리는 여러 번 버렸습니다.

덤프 파일 분석:

a 다수의 long[] 배열이 최대 공간을 차지하고 이상이 있는 것으로 나타났습니다.


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

b gc 루트 노드를 확인하여 대부분을 찾습니다. 이러한 long[] 데이터는 org.HdrHistogram에서 사용되며, 각 Histogram 객체는 2048 크기의 long[]을 보유합니다

c. Histogram 인스턴스 수를 보면 실제로는 일반 스택과 비교하면 50,000개입니다. 프로젝트는 약 100회입니다


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

d. 또 다른 에피소드는 처음에는 매트 분석을 사용했지만 비정상적인 메모리 분석에는 매트에서 생성된 보고서가 더 유용합니다. jvisualvm.exe 및 idea profiler만큼 유용함

원인 해결

로컬에서 시작할 수 있음 본 클래스의 메모리 사용량을 재현하기 위해 일반 메모리와 문제가 있는 애플리케이션으로 로컬 서비스를 시작하고 메모리 비교를 분석했습니다. 여기서는 아이디어 프로파일러를 사용하는데 매우 편리합니다.

정상 애플리케이션을 비교해 보면, 비정상적인 애플리케이션의 참조에


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법● rx.internal의 비정상적인 참조가 포함되어 있는 것으로 나타났습니다. Operators.OnSubscribeReduceSeed$ReduceSeedSubscriber 이러한 비정상적인 참조로 인해 이러한 인스턴스가 새로운 세대에서는 재활용되지 않고 이전 세대에 누적되는 것으로 의심됩니다. 코드를 작성했는데 이유를 알 수 없었습니다. 직접 디버그 비교
Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법시스템에서 관련 코드를 입력하고 히스토그램에 대한 참조를 추가했지만 일반 응용 프로그램에서는 그렇지 않았습니다.

하지만 그 이유를 알 수 없습니다. 이때 왼쪽 하단에 있는 스레드 풀을 주목했는데, 이 스레드 풀은 Hystrix가 자체 대시보드에 대한 관련 지표를 계산하는 데 사용하는 Metric의 스레드 풀입니다. 사용자는 이를 얻기 위해 시스템 회로 차단기 관련 매개변수 및 표시기의 기능을 이해할 수 있습니다. 스택을 다시 살펴보면 여기에 도달하는 논리는


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법이 스트림은 단위 시간당 시스템 표시기를 계산하는 데 사용됩니다. Hystrix는 긴 배열의 히스토그램을 사용하여 단위 시간 내에 지표를 계산하는 슬라이딩 창과 같은 효과를 얻습니다.

Histogram 자체는 단위 시간 내의 트래픽을 계산하기 위해 버킷 + 슬라이딩 창과 유사한 기능을 구현하기 위해 Hystrix에서 사용됩니다. 그러나 지표 매개변수가 켜져 있기 때문에 hystrix는 더 오랜 시간 동안 통계를 수행해야 합니다. 범위 내의 지표에 대해 새 개체는 집계를 위해 더 많은 히스토그램 참조(단위 시간)를 보유합니다. 시간 범위 기간이 길면 참조가 오랫동안 유지되기 때문에 노후화됩니다. 그러나 본질은 메모리 누수가 아니므로 전체 gc마다 재활용할 수 있습니다


문제 해결

위 내용을 참조하세요. 차이점과 이상한 스레드 풀의 첫 번째 반응은 응용 프로그램이 이 논리로 이동하지 않도록 메트릭을 끄는 것입니다. 인용하려면 공식 문서를 참조하세요. 이 구성은 기본적으로 켜져 있으며 이 기능만 확인합니다. 표시기 통계에 영향을 미치며 회로 차단기 자체의 기능에는 영향을 미치지 않습니다. hystrix.metrics.enabled=false 구성을 사용하여 끄세요.

구성을 추가한 후 스택을 확인하고 확인하고 참조가 정상으로 돌아왔으며 시스템을 확인하세요. 한동안 히스토그램 인스턴스를 추가하지 않았는데 온라인에 공개된 후 한동안 관찰해보니 풀 GC 문제는 정말 해결되었습니다
Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법근본 원인

당시 해결 방법을 찾아 검증한 결과, hystrix.metrics.enabled의 기본 구성이 true인 이유를 연구할 시간이 없지만 다른 애플리케이션에는 이 전체 gc 문제가 없습니다. 먼저 해결한 후 계속해서 후속 조치를 취하고 근본 원인을 조사하겠습니다.

이전에 발견한 의심스러운 스레드 풀은 HystrixMetricsPoller입니다. 확인 결과 스레드 풀은 HystrixMetricsPollerConfiguration


클래스에 의해 열립니다. , 기본값은 true입니다. 다른 프로젝트는 왜 활성화되지 않습니까?

소스 코드를 검색해 보니 이 클래스의 활성화가 Annotation과 관련이 있는 것으로 나타났습니다


Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법

코드를 비교해 보니 비정상적인 애플리케이션에서만 이 Annotation을 사용하는 것으로 나타났습니다. on the Circuit breaker

그러나 연구 결과에 따르면 이 주석을 사용하지 않고도 회로 차단기와 같은 기능을 계속 사용할 수 있습니다. 그 이유는 Spring-Cloud 버전 이후 Spring이 hystrix를 사용하여 회로 차단기 대신 openfeign을 캡슐화하기 때문입니다. 전체 hystrix 시스템을 통합하면 spring-cloud도 hystrix 메모리를 발견했을 것입니다. off, 단순히 회로 차단기에 주석을 달기 위해 @EnableCircuitBreaker를 추가하면 효과가 발생하지 않습니다 )

실제로 spring-cloud의 상위 버전에서는 @EnableCircuitBreaker 주석이 더 이상 사용되지 않는 것으로 표시되었지만 아마도 중간 버전이기 때문에 더 이상 사용되지 않는 것으로 표시되지 않고 실제로 쓸모가 없는 상황

간단히 말하면, feign의 회로 차단기 기능은 feign.hystrix.enabled에 의해서만 제어됩니다. @EnableCircuitBreaker 주석을 추가하면 Hystrix

의 다른 모든 표시기와 기타 기능만 활성화됩니다.


위 내용은 Java 메모리의 비정상적인 사용으로 인해 Full GC가 자주 발생하는 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제