JVM 튜닝 원칙 및 온라인 서비스 최적화 관행에 대한 심층 분석

여기에 사진 설명 삽입

  • jvm 튜닝의 이유-jvm 튜닝의 이유! (Hain의 법칙, Murphy의 법칙)
  • jvm 튜닝-가비지 수집 알고리즘의 원리, 튜닝 방법
  • JVM 튜닝 실제 전투 설정 jvm 튜닝 매개 변수 및 이러한 매개 변수를 기반으로 한 스트레스 테스트
  • 로그 상황에 따라 Jvm 튜닝 gc 로그, 서비스 재조정

1 JVM 튜닝이 필요한 이유는 무엇입니까?

생각 1 : 프로젝트가 실행 된 후 jvm 튜닝을 수행하게 된 이유

  • 너무 많은 가비지 (자바 스레드, 객체가 메모리를 차지), 메모리가 가득 차서 프로그램을 실행할 수 없습니다! !
  • 가비지 콜렉션 스레드가 너무 많고 가비지 콜렉션이 잦아서 (가비지 콜렉션 스레드 자체도 메모리, CPU 자원을 차지함) 프로그램 성능이 저하됩니다.
  • 빈번한 가비지 수집으로 STW 발생

따라서 위의 이유에 따라 프로그램이 온라인 상태가 된 후에 조정해야합니다. 그렇지 않으면 프로그램 성능이 향상 될 수 없습니다. 즉, 프로그램이 온라인 상태가 된 후에는 합리적인 가비지 수집 전략을 설정해야합니다.

생각 2 : jvm 튜닝의 본질은 무엇입니까? ?

답변 : 쓰레기를 재활용하고, 사용하지 않는 쓰레기 개체를 적시에 재활용하고, 적시에 메모리 공간을 해제하십시오.

생각 3 : 서버 환경에 따라 jvm 힙 메모리에 얼마나 많은 메모리를 설정해야합니까?

  • 32 비트 운영 체제 주소 지정 용량 2 ^ 32 = 4GB, 최대 용량은 4GB 지원 가능, jvm은 2g + 할당 가능

  • 64 비트 운영 체제 — 주소 지정 기능 2 ^ 64 = 16384PB, 고성능 컴퓨터 (IBM Z unix 128G 200+)
    여기에 사진 설명 삽입

jvm 힙 메모리는 너무 크게 설정 될 수 없습니다. 그렇지 않으면 가비지 주소 지정 시간, 즉 전체 프로그램의 STW가 너무 길어지고 너무 작게 설정할 수 없습니다. 그렇지 않으면 가비지 콜렉션이 너무 자주 발생합니다.

몇 가지 문서 메모를 구성했습니다. 또한 2020 년에 일부 대기업에서 수집 한 인터뷰 자료와 최신 인터뷰 질문을 정리했습니다 (모두 문서로 구성됨, 스크린 샷의 작은 부분). 필요한 경우 여기, 여기 를 클릭 하고 코드 : CSDN을 클릭 하십시오 .

여기에 사진 설명 삽입

여기에 사진 설명 삽입

몇 가지 문서 메모를 구성했습니다. 또한 2020 년에 일부 대기업에서 수집 한 인터뷰 자료와 최신 인터뷰 질문을 정리했습니다 (모두 문서로 구성됨, 스크린 샷의 작은 부분). 필요한 경우 여기, 여기 를 클릭 하고 코드 : CSDN을 클릭 하십시오 .

2 JVM 튜닝 원칙

  1. gc 시간이 충분히 작습니다 (힙 메모리 설정은 충분히 작아야 함).
    여기에 사진 설명 삽입

  2. gc의 수가 충분히 적습니다 (힙 메모리 설정이 충분히 큼) ---- 가비지가 가득 차 (공간을 채우는 데 시간이 오래 걸립니다), 가비지 콜렉션이 시작됩니다.여기에 사진 설명 삽입

  3. full gc cycle 발생이 충분히 길다.
    1) metaspace의 영구 생성 공간 설정이 약간 더 합리적이며, 영구 세대 생성 확장, full gc가 즉시 발생
    2) 구세대가되면 구세대 설정 공간이 더 큼 가득 차지 않음, 가득 차있는 gc는 절대 일어나지 않을 것입니다.
    3) 젊은 세대에서 쓰레기 수거를 허용
    하십시오. 4) 큰 물체를 최소화하십시오

JVM Tuning-GC의 3 가지 원칙

3.1 쓰레기 란?

여기에 사진 설명 삽입
메모리에는 참조 된 개체가 없으며 이러한 개체는 가비지이며 힙 메모리에서는 개체 참조가 사라진 다음 개체를 재활용해야합니다.

3.2 쓰레기를 찾는 방법?

JVM에는 2 가지 종류의 가비지 검색 알고리즘이 있습니다 (가비지 찾기 방법).

  • 참조 계산 알고리즘
  • 루트 도달 가능성 알고리즘

1) 참조 계수 알고리즘
여기에 사진 설명 삽입
객체가 쓰레기라고 판단하는 참조 계수 알고리즘은 계수가 0 일 때 객체가 쓰레기라고 판단하는 방법, 문제가 있음 : 순환 참조 계수 문제를 해결할 수 없음,
여기에 사진 설명 삽입
위 객체는 서로를 참조하여 참조 횟수를 계산합니다. 항상 0이 아니므로 쓰레기로 판단 할 수 없지만 이러한 객체는 외부 객체에 의해 참조되지 않으므로 쓰레기입니다.

2) 루트 도달 가능성 알고리즘

여기에 사진 설명 삽입
루트 도달 가능성 알고리즘은 현재 JVM에서 사용하는 주요 가비지 수집 알고리즘이며 Oracle 핫스팟은이 알고리즘을 사용합니다.

3.3 쓰레기는 어떻게 제거하나요?

JVM은 3 가지 방법 (알고리즘)을 제공합니다.

1. 마크 스윕 마크 제거 알고리즘
2. 복사 복사
3. 마크 압축 마크 압축 알고리즘

1) Mark-sweep — Mark-sweep 알고리즘

여기에 사진 설명 삽입
1. 메모리 공간에서 쓰레기를 검색하고 발견 된 쓰레기를 표시합니다
. 2. 표시된 쓰레기를 제거합니다.

  • 장점 : 간단하고 효율적
  • 단점 : 불연속적인 메모리 공간이 많고 메모리 공간이 조각화되어 주소 지정 효율성과 성능이 저하됩니다.

2) 복사-복사
여기에 사진 설명 삽입
1. 남은 개체를 선택합니다
. 2. 남은 개체를 연속 메모리 공간 인 나머지 절반에
복사합니다. 3. 남은 개체를 모두 복사 한 후 공간 의 위쪽 절반을 직접 정리하여 쓰레기를 완료합니다. 수집;

장점 : 단순하고 메모리 공간이 연속적이며
메모리 공간의 조각화에 대해 걱정할 필요가 없습니다 . 단점 : 메모리 공간 낭비

3) 표시 압축 표시 압축 알고리즘
여기에 사진 설명 삽입
1, 쓰레기 표시, 쓰레기 삭제 안 함
2, 다시 스캔하고, 남아있는 개체 (표시되지 않은 개체)를
한쪽 끝으로 슬라이드 (복사) 3. 다른 쪽 끝의 메모리 공간에서 쓰레기 회수

3.4 사용 가능한 가비지 수집기

Java 언어에는 기능이 있고 자체 가비지 수집기가 있으며 많은 가비지 수집기가 있습니다. 따라서 다른 시나리오에 따라 다른 가비지 수집기를 선택해야합니다
여기에 사진 설명 삽입
.JVM은 10 가지 종류의 가비지 수집기를 제공합니다. 프로젝트에서 가비지 수집기 조합이 사용됩니까? ?

1) 직렬 (젊은 세대 가비지 수집) + serialOld (이전 세대의 쓰레기 재활용) : 직렬화 된 수집기이므로 현재 멀티 코어 CPU에서는 적합하지 않으며 단일 코어 CPU 가비지 수집에만 적합합니다.

2) parNew + CMS : 병렬, 동시 가비지 수집기,이 조합은 응답 시간에서 가비지 수집기 조합의 우선 순위를 지정합니다.

3) Parallel Scavenge + Parallel Old (약어 : ps + po) : jdk의 기본 가비지 수집기 조합 인 동시 가비지 수집기

4) g1 가비지 수집기 (논리적 세대) : 가비지 수집을 위해 젊은 세대와 구세대를 하나로 결합합니다.

3.5 직렬 가비지 수집기

4 메모리 생성 모델

여기에 사진 설명 삽입
질문 : 큰 물체가 나온 후 무엇을합니까? 에덴은 그것을 내려 놓을 수 있습니까?

— 아니요 — (YGC) — eden이 내려 놓을 수 있습니까? — 아니요 ---- 이전 버전은 다운 될 수 있음 ---- 예 — 이전 버전으로 배치 가능 ----- 아니요 ---- fullgc oom

5 JVM 튜닝 실제 전투

서버 구성 : 4cpu, 8GB 메모리 ---- jvm 튜닝은 실제로 합리적인 크기의 jvm 힙 메모리를 설정하는 것입니다 (너무 크지도 작지도 않음).

-Xmx3550m  设置jvm堆内存最大值  (经验值设置: 根据压力测试,根据线上程序运行效果情况)
-Xms3550m  设置jvm堆内存初始化大小,一般情况下必须设置此值和最大的最大的堆内存空间保持一致,防止内存抖动,消耗性能
-Xmn2g 设置年轻代占用的空间大小
-Xss256k 设置线程堆栈的大小;jdk5.0以后默认线程堆栈大小为1MB; 在相同的内存情况下,减小堆栈大小,可以使得操作系统创建更多的业务线程;

Jvm 힙 메모리 설정 :

nohup java -Xmx3550m -Xms3550m -Xmn2g -Xss256k -jar jshop-web-1.0-SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

TPS 성능 곡선 :
여기에 사진 설명 삽입

5.2 gc 로그 분석

gc 로그를 분석해야하는 경우 서비스 gc가 gc 세부 사항을 로그 로그 파일에 입력하도록 한 다음 해당 gc 로그 분석 도구를 사용하여 로그를 분석해야합니다.

gc 분석을 위해 gc 세부 사항을 gc.log 로그 파일에 출력

-XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintGCDateStamps
-XX : + PrintHeapAtGC -Xloggc : gc.log

처리량 : 비즈니스 스레드 실행 시간 / (gc 시간 + 비즈니스 스레드 시간)
여기에 사진 설명 삽입
gc 로그를 분석하여 처음에 3 개의 fullgc가 발생했음을 발견했습니다. jvm 최적화 매개 변수 설정에 문제가 있음이 분명합니다.
여기에 사진 설명 삽입
원인을 확인하십시오. fullgc 문제 : jstat- gcutil pid
여기에 사진 설명 삽입
메타 스페이스 영구 생성 :
초기 할당 크기는 20m입니다. 메타 스페이스가 가득 차면 영구 생성을 확장해야합니다. 메타 스페이스가 매번 확장되면 fullgc를 한 번 실행해야합니다 (fullgc 회수). 시간이 걸리는 전체 힙 공간)

gc 구성 조정 : 영구 생성 공간의 초기화 크기를 수정합니다.

nohup java -Xmx3550m -Xms3550m -Xmn2g -Xss256k -XX : MetaspaceSize = 256m -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintGCDateStamps -XX : + PrintHeapAtGC -Xloggc : gc.log -jar jshop-web-1.0- SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

튜닝 후 fullgc 현상이 사라졌습니다.
여기에 사진 설명 삽입

5.3 노년층 비율

젊은 세대와 구세대의 비율 : 1 : 2 매개 변수 : -XX : NewRetio = 4, 이는 젊은 세대 (eden, s0, s1)와 이전 세대의 비율이 1 : 4임을 의미합니다.

1) -XX : NewRetio = 4
여기에 사진 설명 삽입젊은 세대가 할당 한 메모리 크기가 작아 져 YGC의 수가 늘어 났고 fullgc는 일어나지 않지만 YGC는 더 많은 시간이 걸립니다!

2) -XX : NewRetio = 2 YGC 발생 횟수는 필연적으로 감소합니다. 에덴 영역의 크기가 커지기 때문에 YGC가 감소합니다.
여기에 사진 설명 삽입

5.4 에덴 & S0S1

YGC를 더 줄이기 위해 enden과 s 영역의 비율을 설정할 수 있습니다. 설정 방법 : -XX : SurvivorRatio = 8

1) 설정 비율 : 8 : 1 : 1

여기에 사진 설명 삽입
2) Xmn2g 8 : 1 : 1

nohup java -Xmx3550m -Xms3550m -Xmn2g -XX : SurvivorRatio = 8 -Xss256k -XX : MetaspaceSize = 256m -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintGCDateStamps -XX : + PrintHeapAtGC -Xloggc : gc.log -jar jshop-web-1.0-SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

gc 조정에 따르면 가비지 콜렉션 수, 시간 및 처리량은 모두 상대적으로 최적의 구성입니다.
여기에 사진 설명 삽입

5.5 처리량 우선 순위

병렬 가비지 컬렉터를 사용하면, 당신은 도움이 가비지 컬렉션에 멀티 코어 CPU의 전체를 사용을 할 수 있으며, 이러한 GC 방법은 처리량 첫 번째 튜닝 방법이라고합니다.
가비지 컬렉터 조합 : PS (병렬 소기) + 포 (옛 평행을)
이 가비지 수집기는 Jdk1.8의 기본 가비지 수집기 조합입니다.

nohup java -Xmx3550m -Xms3550m -Xmn2g -XX : SurvivorRatio = 8 -Xss256k -XX : + UseParallelGC -XX : UseParallelOldGC -XX : MetaspaceSize = 256m -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintXXGCDateStamps PrintHeapAtGC -Xloggc : gc.log -jar jshop-web-1.0-SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

5.6 응답 시간 우선 순위

cms 가비지 수집기를 사용하는 것은 응답 시간 우선 순위의 조합입니다 .cms 가비지 수집기 (가비지 수집 및 비즈니스 스레드 교차 실행은 비즈니스 스레드가 stw를 중단하도록 허용하지 않음)를 최대한 많이 사용하여 stw의 시간을 줄이므로 cms를 사용하십시오. 가비지 수집기 조합은 응답 시간 우선 순위 조합입니다.

nohup java -Xmx3550m -Xms3550m -Xmn2g -XX : SurvivorRatio = 8 -Xss256k -XX : + UseParNewGC -XX : UseConcMarkSweepGC -XX : MetaspaceSize = 256m -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintXXGCDateStamps -XXGCDateStamps PrintHeapAtGC -Xloggc : gc.log -jar jshop-web-1.0-SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

cms 가비지 수집기 시간이 길어지는 것을 알 수 있습니다.

5.7g1

구성 방법은 다음과 같습니다.

nohup java -Xmx3550m -Xms3550m -Xmn2g -XX : SurvivorRatio = 8 -Xss256k -XX : + UseG1GC -XX : MetaspaceSize = 256m -XX : + PrintGCDetails -XX : + PrintGCTimeStamps -XX : + PrintGCDateStamps -XX : + PrintHeapAtGC -Xloggc : gc.log -jar jshop-web-1.0-SNAPSHOT.jar --spring.addition-location = application.yaml> jshop.log 2> & 1 $ &

여기에 사진 설명 삽입

주의를 기울이고 길을 잃지 마십시오! 이 기사가 도움이된다면 좋아요와 지원을 잊지 마세요!

여기에 사진 설명 삽입

추천

출처blog.csdn.net/qq_41770757/article/details/109607679