JVM Metaspace 메모리 넘 침 문제 해결 방안
얼마 전에 회사 온라인 환경의 자바 응용 프로그램 은 OOM 의 이상 경보 로 인해 전체 서비스 가 클 러 스 터 에서 끌 어 낼 수 없 었 습 니 다.로 컬 모 의 재현 현상 은 다음 과 같 습 니 다.
당시 의 해결 방안 은 metaspace 의 용량 을 증가 시 키 는 것 이 었 다.-XX:MaxMetaspace Size=500 m 는 원래 의 기본 256 m 에서 500 m 로 바 뀌 었 다.oom 이 다시 나타 나 지 않 았 지만 이것 은 임시 해결 방안 일 뿐 회사 의 모니터링 시스템 을 통 해 metaspace 의 사용 상황 이 증가 하고 있 는 것 을 관찰 한 다음 에 업무 방 문 량 이 점점 커지 면서 한도 값 에 도달 할 수 있 었 다.
분석
Metascace 메타 공간 은 주로 저장 류 의 메타 데이터 정보 입 니 다.우리 의 응용 에 불 러 온 각종 설명 정보,예 를 들 어 클래스 이름,속성,방법,방문 제한 등 은 일정한 구조 에 따라 Metascace 에 저 장 됩 니 다.
이 를 통 해 알 수 있 듯 이 metaspace 공간 증 가 는 반사 류 로 딩,동적 에이전트 가 생 성 한 클래스 로 딩 등 으로 인 한 것 이다.즉,Metaspace 의 크기 는 로 딩 류 의 데이터 와 관계 가 있 고 로 딩 류 가 많 을 수록 metaspace 가 사용 하 는 메모리 도 커진다.
그 당시 의 업무 장면 을 알 고 있 는 이 유 는 메 일 서비스 가 주문 상세 인터페이스 에 접근 하 는 방 문 량 이 갑자기 증가 하고 log 의 eroor 로 그 를 보 니 대부분 주문 상세 인터페이스 에서 먼저 보 고 된 이 문제 가 있 었 기 때 문 입 니 다.java.lang.OutOf Memory Error:Metaspace
여기 서 저 는 테스트 환경 자바 응용 jvm 에-XX:+TraceClass Loading-XX:+TraceClass Unloading 에서 다음 과 같은 로 딩 과 마 운 트 해제 상황 을 기록 한 다음 에 jmeter 여러 스 레 드 를 통 해 주문 상세 한 인 터 페 이 스 를 호출 하여 metaspace 가 넘 치 는 현상 을 모 의 한 결과 catalina.out 파일 에서 지 는 것 은 업무 에 사용 되 는 클래스 를 제외 하고 대량의 반사 류 가 있 음 을 발 견 했 습 니 다.다음 과 같 습 니 다.
이러한 반사 류 가 빈번하게 로드 되 고 마 운 트 해제 되 는 것 은 정상 적 이지 않다.Arthas 진단 도 구 를 통 해 호출 체인 을 관찰 한 결과 매번 호출 인터페이스 가 반사 적 인 방식 으로 이 루어 진 것 을 발견 했다.
현재 우리 의 프로젝트 는 모두 SOA 프레임 워 크 를 바탕 으로 대외 적 으로 방문 을 제공 하고 있 으 며,위의 그림 sun.reflect 호출 자 에서 도 알 수 있 습 니 다.
위의 그림 을 통 해 알 수 있 듯 이 바 텀 인 터 페 이 스 를 호출 할 때 모두 반사 적 인 방식 으로 클래스 의 인 스 턴 스 를 얻 고 프레임 바 텀 코드 를 보면 확인 할 수 있다.
마찬가지 로 바 텀 인터페이스 에서 돌아 오 는 제 이 슨 데이터 의 역 직렬 화 에 도 반사 가 사용 된다.
코드 를 계속 따라 가면 반 사 된 실현 을 볼 수 있 습 니 다.자바.lang.Class 의 ReflectionData 대상 을 사용 합 니 다.
ReflectionData 는 내부 정적 클래스 가 캐 시 되 어 있 습 니 다.그 안의 속성 은 우리 가 반사 작업 을 할 때 사용 해 야 할 속성 Field,방법 Method 와 구조 함수 등 입 니 다.그러나 문제 가 있 습 니 다.reflection Data 는 SoftReference 소프트 에 의 해 인용 되 어 수식 되 었 습 니 다.다음 과 같 습 니 다.
부 드 러 운 인용 이 라면 메모리 공간 이 부족 할 때 회수 할 수 있 습 니 다.회수 하면 다음 에 사용 하면 반사 로 만 다시 가 져 올 수 있 습 니 다.
한편,SoftReference 가 회수 되 었 는 지 여 부 는 SoftRefLRUPolicy MSPerMB 매개 변수 값 과 관계 가 있 습 니 다.온라인 JVM 의 설정 을 살 펴 보면 XX:SoftRefLRUPolicy MSPerMB 라 는 매개 변 수 는 0 으로 설정 되 어 있 습 니 다.
SoftRefLRUPolicy MSPerMB 라 는 매개 변 수 는 1M 의 빈 공간 마다 유지 할 수 있 는 SoftReference 대상 의 생존 시간(단 위 는 ms 밀리초)을 의미 하 며,LRU 는 Least Recently Used 의 줄 임 말로 최근 가장 적 게 사용 되 고 있다.
이 값 jvm 은 기본적으로 1000 ms 입 니 다.0 으로 설정 되면 소프트 인용 대상 이 바로 회수 되 고 새로운 종 류 를 자주 생 성하 여 재 활용 효 과 를 얻 지 못 할 수 있 습 니 다.
위의 그림 에서 대량의 sun.reflect.Generated Serialization Constructor Accessor,Generated MethodAccessor 가 이렇게 생 겼 다.
나 는 이 매개 변 수 를 기본 값-XX:SoftRefLRUPolicy MSPerMB=1000(1 초)으로 바 꾸 었 고 생산 환경 검증 하에 발표 한 후에 내 려 왔 으 며 지금까지 기본적으로 안정 되 었 다.
조정 후 기본적으로 다시 파동 이 나타 나 지 않 았 다.
총화
여기 서 하 는 대상 복사 작업 은 apache common-beanutils.jar 의 BeanUtils 를 사용 합 니 다.이런 바 텀 은 javabeans+반사 로 실현 되 고 성능 이 떨 어 지 며 메모리 비용 이 비교적 많 습 니 다.시스템 이 높 고 병행 하 는 상황 에서 Metaspace 공간 이 너무 빨리 증가 하기 쉬 우 므 로 이렇게 사용 하 는 것 을 권장 하지 않 습 니 다.
필드 가 적 으 면 직접 값 을 부여 하면 됩 니 다.많 으 면 Cglib 의 BeanCopier 류 를 사용 할 수 있 습 니 다.BeanCopier 류 의 바 텀 은 asm 바이트 코드 조작 방식 으로 대상 복사 작업 을 할 수 있 고 성능 손실 과 메모리 비용 이 비교적 적 습 니 다.
또는 MapStruct 라 는 set,get 방법 을 만 드 는 도 구 를 사용 하면 효과 가 좋 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
IntelliJ IDEA 2019.2의 새로운 기능 프로파일 러를 사용해 보았습니다.이번의 새로운 기능은 초호화! 저는 퍼포먼스 개선을 자주 합니다만, IntelliJ IDEA에도 프로파일링 툴이 붙게 되었으므로, 사용해 보았습니다. 편리한 것 같았기 때문에, 앞으로의 메인 웨폰은 이것이 될 것 같...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.