>  기사  >  Java  >  Java 지식 요약 및 JVM에 대한 자세한 설명

Java 지식 요약 및 JVM에 대한 자세한 설명

WBOY
WBOY앞으로
2022-07-12 17:20:031975검색

이 기사는 JVM 메모리 영역 분할, JVM 클래스 로딩 메커니즘, VM 가비지 수집 등 JVM 관련 문제를 주로 정리하는 java에 대한 관련 지식을 제공합니다. 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

Java 지식 요약 및 JVM에 대한 자세한 설명

추천 학습: "java 동영상 튜토리얼"

1. JVM 메모리 영역 분할

JVM은 왜 이러한 영역을 분할하는가? JVM 메모리는 운영체제부터 적용하고, JVM은 기능을 기반으로 필요하다. 이를 몇 개의 작은 모듈로 나누어서 큰 사이트를 몇 개의 작은 모듈로 나누고 각 모듈이 자체 기능을 담당하는지 살펴보겠습니다.

1. 프로그램 카운터

프로그램 카운터는 메모리에서 가장 작은 영역으로 주로 다음에 실행할 명령어의 주소를 저장합니다. (명령어는 바이트코드입니다. 일반적으로 프로그램은 JVM에 의해 실행되어야 합니다. 바이트코드를 메모리에 로드하면 프로그램이 메모리에서 명령어를 하나씩 가져와 실행을 위해 CPU에 올려놓기 때문에 현재 어떤 명령어가 실행되고 다음 명령어가 어디에 있는지 기억해야 하기 때문이다. CPU는 하나의 프로세스에만 서비스를 제공하는 것이 아니라 모든 프로세스에 서비스를 제공하고 동시에 프로그램을 실행한다. 그리고 운영체제는 스레드 단위로 실행을 스케줄링하기 때문에 각 스레드는 자신만의 실행 위치, 즉 스레드마다 필요하다. 위치를 기록하는 프로그램 카운터!)2. 스택

스택은 주로

로컬 변수 및 메소드 호출 정보

를 저장하며, 새로운 메소드 호출이 포함되는 한 매 마다 "푸시" 작업이 수행됩니다. 메서드가 실행될 때 "푸시" 작업이 발생하고 각 스레드에는 스택
의 복사본이 있습니다. 따라서 재귀의 경우 재귀 조건을 제어해야 하며 그렇지 않으면 스택 오버플로(StackOverflowException) 예외가 발생할 수 있습니다. Java 지식 요약 및 JVM에 대한 자세한 설명
3. 힙

힙은 메모리에서 가장 큰 공간이며, 힙은 각 프로세스에 대해 단 하나의 복사본이며 프로세스 내 여러 스레드에 의해 공유되는 힙입니다. 주로 새 개체와 개체의 멤버 변수를 저장합니다. 예를 들어 String s = new String() 메서드의 여기 s가 스택의 지역 변수인 경우 이 s가 멤버 변수인 경우 힙에 있습니다. 그리고 new String()은 객체의 온톨로지입니다. 객체가 힙에 있기 때문에 혼동하기 쉽습니다. 또한 힙의 또 다른 중요한 점은 가비지 수집 문제입니다. 이에 대해서는 나중에 자세히 소개하겠습니다.

4. 메소드 영역

메소드 영역 은 "클래스 객체"

를 저장합니다. 일반적으로 작성하는 .java 코드는 컴파일러에 의해 변환된 후 .class(바이너리 바이트 코드)가 되며, .class는 메모리에 로드되고 JVM에 의해 클래스 객체로 구성되며(로딩 프로세스를 "클래스 로딩"이라고 함) 이러한 클래스 객체는 클래스 길이(클래스 이름, 클래스의 멤버)를 구체적으로 설명하는 메소드 영역에 저장됩니다. 클래스와 그 멤버 이름, 멤버 유형, 클래스의 메서드와 해당 메서드 이름, 메서드 유형 및 일부 지침... 또한 클래스 개체에는 매우 중요한 것이 저장되는데, 이는 일반적으로 정적 멤버입니다. 정적 수정 멤버는 클래스 속성이 되고, 일반 메서드는 인스턴스 속성이라고 하는데 이는 매우 다릅니다!

위 소개는 JVM의 공통 영역이며 일부 JVM 메모리 영역 구분이 반드시 실제와 일치하지는 않습니다. JVM 구현 프로세스의 영역 구분은 다릅니다. JVM의 제조업체와 버전에 따라 차이가 있을 수 있습니다. 그러나 일반 프로그래머의 경우 JVM을 구현하지 않는 한 필요하지 않습니다. 위의 공통 영역에 대해 이야기하고 이해하십시오!

2. JVM 클래스 로딩 메커니즘

클래스 로딩은 실제로 런타임 환경을 설계하는 방법이므로 중요한 핵심 기능은 매우 무겁습니다.

위는 클래스 로딩의 구체적인 과정입니다. 마지막 사용 및 언로딩은 여기서는 소개하지 않겠습니다.

1.로드

로딩 단계에서는 먼저 해당 .class 파일을 찾은 다음 (바이트 스트림에 따라) .class 파일을 열고 읽으며 동시에 처음에 클래스 객체를 생성합니다. 클래스 파일의 특정 형식(Java 컴파일러를 구현하려면 이 형식으로 구성해야 하고 JVM을 구현하는 경우 로드해야 함) ):

Java 지식 요약 및 JVM에 대한 자세한 설명 이 형식을 보면 .class 파일이 .java 파일의 핵심 정보를 모두 표현하고 있음을 알 수 있습니다. 하지만 구성 형식이 변경되어 로딩 링크는 다음을 사용하게 됩니다. 정보를 미리 입력합니다.

2. 연결(연결)

연결은 일반적으로 여러 엔터티 간의 연결을 설정합니다.

2.1. 검증(검증)

검증은 주로

판독 검증을 수행합니다. 수신된 내용이 사양에 명시된 형식과 정확히 일치합니까? 읽은 데이터의 형식이 사양을 따르지 않는 것으로 확인되면 클래스 로딩이 실패하고 예외가 발생합니다. 2.2.

준비 단계는

정의된 변수(정적 변수, static으로 수정되는 변수)에 대해 정식으로 메모리를 할당하고 클래스 변수의 초기값을 설정하는 단계

에서 각 정적 변수에 메모리를 할당하고 a value of 0! 2.3.해결(분석) 해결 단계는 Java 가상 머신이 상수 풀에 있는 기호 참조를 직접 참조로 바꾸는 과정으로, . class 파일은 중앙에 배치되며 각 상수에는 숫자가 있습니다. .class 파일 구조의 초기 상황은 레코드 번호일 뿐이며 이 숫자를 기반으로 해당 내용을 찾은 다음 해당 내용을 입력할 수 있습니다. 클래스 객체!

3. 초기화(Initialization)

초기화 단계는 클래스 객체를 실제로 초기화합니다(작성된 코드에 따라), 특히 정적 멤버의 경우

4. 일반적인 인터뷰 질문

class A {
    public A(){
        System.out.println("A的构造方法");
    }
    {
        System.out.println("A的构造代码块");
    }
    static {
        System.out.println("A的静态代码块");
    }}class B extends A{
    public B(){
        System.out.println("B的构造方法");
    }
    {
        System.out.println("B的构造代码块");
    }
    static {
        System.out.println("B的静态代码块");
    }}public class Test extends B{
    public static void main(String[] args) {
        new Test();
        new Test();
    }}

시도해 볼 수 있습니다. 먼저 출력 결과를 직접 작성하세요.

이러한 질문을 마스터해야 합니다. 몇 가지 주요 원칙:


정적 코드 블록은 클래스 로딩 단계에서 실행됩니다. 인스턴스를 생성하려면 먼저 클래스 로딩을 수행해야 합니다.

    정적 코드 블록은 클래스 로딩 단계에서 한 번만 실행되며, 다른 모든 단계는 다시 실행되지 않습니다.
  • 구성 방법 및 구성 코드 블록은 인스턴스화될 때마다 실행되며, 생성 메소드 앞에서 생성 코드 블록이 실행됩니다~~
  • 상위 클래스가 먼저 실행되고 하위 클래스가 나중에 실행됩니다!
  • 프로그램은 테스트 메소드인 main에서 실행됩니다. main을 실행하려면 먼저 Test 클래스를 로드해야 합니다
  • 이 클래스가 포함될 때만 클래스에 있는 항목이 로드됩니다.
  • 输出结果:
    A的静态代码块
    B的静态代码块
    A的构造代码块
    A的构造方法
    B的构造代码块
    B的构造方法
    A的构造代码块
    A的构造方法
    B的构造代码块
    B的构造方法
  • 5. 부모 위임 모델
  • 이것은 클래스 로딩의 링크입니다. 로딩 단계(이전 부분)에 있습니다. 상위 위임 모델

    은 JVM의 클래스 로더, 클래스의 정규화된 이름(java.lang.String)을 사용하는 방법을 설명합니다. .class 파일을 찾는 중
  • . 여기서 클래스 로더는 JVM에서 특별히 제공하는 객체로 주로 클래스 로딩을 담당하므로, 파일을 찾는 과정도 클래스 로더가 담당한다. 그것들은 JDK 디렉토리에 배치되어야 하며 일부는 프로젝트 디렉토리에 배치되고 일부는 다른 특정 위치에 배치됩니다. 따라서 JVM은 여러 클래스 로더를 제공하고 각 클래스 로더는 슬라이스를 담당하며 주로 3개의 기본 클래스가 있습니다. 로더:

BootStrapClassLoader: 표준 라이브러리(String, ArrayList, Random, Scanner...)의 클래스 로드를 담당합니다.

    ExtensionClassLoader: JDK 확장 클래스 로드를 담당합니다(현재는 거의 사용되지 않음)
  • ApplicationClassLoader : 프로젝트 디렉토리의 현재 클래스를 로드하는 역할을 담당합니다
  • 또한 프로그래머는 클래스 로더를 사용자 정의하여 다른 디렉토리의 클래스를 로드할 수도 있습니다. Tomcat은 웹앱에서 .classes를 특별히 로드하도록 클래스 로더를 사용자 정의했습니다. 위임 모델은 디렉토리를 찾는 과정, 즉 위의 클래스 로더가 어떻게 협력하는지 설명합니다. java.lang.String을 찾아보세요.
  • 프로그램이 시작되면 먼저 ApplicationClassLoader 클래스 로더로 들어갑니다
  • ApplicationClassLoader 클래스 로더는 상위 로더가 로드되었는지 여부를 확인합니다. 그렇지 않은 경우 상위 클래스 로더를 호출합니다. ExtensionClassLoader

ExtensionClassLoader 클래스 로더는 상위 로더가 로드되었는지 여부도 확인합니다. 로드된 후 아버지가 없음을 발견하고 책임 디렉터리를 스스로 스캔합니다

  • 그러면 표준 라이브러리에서 java.lang.String 클래스를 찾을 수 있고, 이후의 로딩 프로세스는 BootStrapClassLoader 로더가 담당하게 되며 검색 프로세스는 종료됩니다!
    Java 지식 요약 및 JVM에 대한 자세한 설명

  • 뭔가를 찾아보세요 직접 작성한 테스트 클래스: 프로그램이 시작되면 먼저 ApplicationClassLoader 클래스 로더에 들어갑니다. ApplicationClassLoader 클래스 로더는 상위 로더가 로드되었는지 확인합니다. 그렇지 않은 경우 ExtensionClassLoader 클래스 로더를 호출합니다. 상위 로더가 로드되었는지 확인합니다. 그렇지 않은 경우 상위 클래스 로더인 BootStrapClassLoader

    • BootStrapClassLoader가 로드되었는지 여부도 확인합니다. father가 아니므로 자신이 담당하는 디렉토리를 스캔하고, 스캔되지 않으면 하위 로더로 돌아가서 스캔을 계속합니다.

    • ExtensionClassLoader는 자신이 담당하는 디렉토리를 스캔하지만 스캔 후 아무 것도 없습니다. , 서브로더로 돌아가서 스캔을 계속하세요.

    • ApplicationClassLoader는 자신이 담당하는 디렉터리도 스캔합니다. 여러분이 작성한 클래스는 자신의 프로젝트 디렉터리에 있으므로 찾을 수 있으며 이후의 클래스 로딩은 ApplicationClassLoad에 의해 완료됩니다. , 이때 디렉터리 검색 과정은 끝났습니다~~(또한 ApplicationClassLoader가 찾지 못하면 ClassNotFoundException 예외가 발생합니다)

    • 이 검색 규칙 집합을 상위 위임이라고 합니다. 그렇다면 JVM에는 왜 모델이 필요한가? 이 설계의 이유는 프로그래머가 작성한 클래스가 동일한 정규화된 클래스 이름을 가지면 프로그래머가 작성한 클래스 대신 표준 라이브러리의 클래스를 성공적으로 로드할 수 있기 때문입니다!! !
    • 또한, 사용자 정의 클래스 로더인 경우 이 상위 위임 모델을 준수하시겠습니까?

      준수할 수 있는지 여부는 주로 요구 사항에 따라 다릅니다. 예를 들어 Tomcat이 클래스를 로드하는지 여부입니다. webapp에서는 위 사항을 준수하는 클래스 로더를 찾을 수 없기 때문에 준수하지 않습니다. !

    • 3. JVM의 가비지 수집
    • JVM의
      가비지 수집 메커니즘Java 지식 요약 및 JVM에 대한 자세한 설명. 코드의 경우 변수 생성, 새 객체 생성, 메서드 호출, 클래스 로드 등 메모리 신청이 포함되는 경우가 많습니다. 메모리 신청 시기는 일반적으로 명확합니다(저장해야 하는 경우 메모리 신청 필요). 특정 데이터 또는 특정 데이터), 그러나 메모리 해제 시점이 명확하지 않고 너무 일찍 해제되면 작동하지 않습니다(아직 사용해야 하지만 결과적으로 해제된 경우 사용할 수 있는 메모리가 없고, 데이터가 "갈 곳이 없다"는 점), 너무 늦게 출시되면 작동하지 않습니다(늦게 출시되면 대량의 비축으로 인해 사용할 수 있게 될 가능성이 높음). 메모리가 점차 적어지면 메모리 누수가 발생할 가능성이 매우 높으므로(즉, 사용할 메모리가 없음)

      메모리 해제가 적절해야 합니다
    • !
    가비지 수집 작업은 많은 추가 메모리에 의존합니다. 런타임 환경에서 수행되는 작업을 완료하면 프로그래머의 정신적 부담이 크게 줄어들지만

    가비지 수집에도 단점이 있습니다: ① 추가 오버헤드가 소모됩니다(더 많은 리소스가 소모됩니다). ② 원활한 작업에 영향을 줄 수 있습니다. 프로그램 실행(가비지 수집은 종종 STW 문제를 발생시킵니다(Stop The World))

    가비지 수집은 어떤 종류의 메모리를 모두 재활용해야 합니까?

    물론 아닙니다. 위의 네 가지 영역을 사용하여 설명하겠습니다.

    프로그램 카운터: 이 메모리는 고정된 크기이고 릴리스를 포함하지 않으므로 GC가 필요하지 않습니다. 스택: 함수 호출이 완료되면 해당 스택 프레임이 자동으로 릴리스되며 GC가 필요하지 않습니다. ; Heap : GC가 가장 많이 필요한 메모리입니다. 일반 코드에서 많은 양의 메모리가 힙에 있습니다.
    이 세 가지 영역 중 어떤 영역이 해제되어야 합니까? 사용되지 않으며 일부는 더 이상 사용되지 않습니다. 일반적으로 개체가 더 이상 사용되지 않는 경우에만 해제되므로 개체의 절반이 GC에 나타나지 않습니다. 컬렉션은 바이트 대신 객체입니다!

    메서드 영역: 클래스 객체, 클래스 로딩, 클래스가 언로드될 때만 메모리를 해제해야 하며 언로드 작업의 빈도가 매우 낮아 거의 수행되지 않습니다. GC를 포함하세요!


      재활용 방법을 자세히 살펴보겠습니다.
    • 1. 쓰레기 찾기/쓰레기 결정
    • 현재 두 가지 주류 솔루션이 있습니다.

    • 1.1 참조 계산을 기반으로 합니다. Java에서 채택한 솔루션이 아니라 Python 및 기타 언어에 대한 솔루션이므로 너무 자세히 설명하지 않고 여기서 간단히 소개하겠습니다~Java 지식 요약 및 JVM에 대한 자세한 설명 참조 카운팅의 구체적인 아이디어는 각 객체에 대해 추가로 작은 이 개체에 대한 참조 수를 저장하기 위해 메모리 조각이 도입됩니다.
      그리고 이러한 참조 카운트에는 두 가지 결함이 있습니다.
      • 공간 활용도가 상대적으로 낮습니다!!!, 각각의 새로운 객체에는 카운터가 장착되어야 합니다. 카운터가 4바이트라고 가정할 때, 객체 자체가 비교적 큰 경우(수백 바이트) 이 카운터는 그렇지 않습니다. 문제이며 개체 자체가 상대적으로 작으면(4바이트) 추가 4바이트는 공간 활용을 두 배로 늘리는 것과 동일하므로 공간 활용은 상대적으로 낮습니다~
      • 루프가 있습니다. 참조 문제
        Java 지식 요약 및 JVM에 대한 자세한 설명
        따라서 참조 카운팅을 사용할 때 많은 문제가 발생합니다. Python 및 PHP와 같은 언어는 참조 카운터를 사용하여 GC를 완료할 뿐만 아니라 이를 완료하기 위해 다른 메커니즘도 사용합니다. 도달 가능성 분석
      도달 가능성 분석은 일부 추가 스레드

      를 통해 전체 메모리 공간의 개체를 주기적으로 검사하는 것입니다. 단, 시작 위치(GCRoots)는 다음과 유사합니다. 깊이 우선 순회(트리로 상상 가능), 접근 가능한 모든 객체를 한쪽에 표시하지만(표시된 객체는 도달 가능한 객체임) 표시되지 않습니다. 객체는 도달할 수 없는 객체, 즉 가비지이므로 해제해야 합니다. 여기에서 GCRoots(이 위치에서 탐색 시작):

      스택의 로컬 변수
      상수 풀의 참조가 가리키는 개체

        메서드 영역의 정적 멤버가 가리키는 개체;
      • 그래서 도달 가능성 분석의 장점은 참조 카운팅의 단점인 낮은 공간 활용도와 순환 참조
      • 를 해결한다는 것입니다. 그리고 도달 가능성 분석의 단점도 명백합니다.
      • 시스템 오버헤드가 높고 한 번 탐색하는 것이 느릴 수 있습니다
      • ~
      .

      그래서 쓰레기를 찾는 것도 매우 간단합니다. 이 객체가 앞으로 사용될 것인지, 이를 가리키는 참조가 있는지, 해제해야 하는지 확인하는 것이 핵심입니다! 2. 쓰레기를 해제하세요 이제 쓰레기가 무엇인지 명확히 했으니 다음 단계는 쓰레기를 재활용하는 것입니다. 쓰레기 재활용을 위한 세 가지 기본 전략을 살펴보겠습니다.

      2.1. 마크 - 여기에서

      제거하세요. 도달성 분석 과정, 삭제는 메모리를 해제하는 것입니다

      . 위 내용을 메모리 조각으로 가정하고, 이때 체크된 영역을 가비지라고 가정하면, 메모리는 시스템으로 반환되지만, 메모리는 연속적이지 않고 분리되어 있으며 이로 인해 발생하는 문제는 여유 메모리가 많을 수 있습니다. 500MB의 공간을 신청한다고 가정합니다. 이번에 신청은 가능하지만 여기서는 신청이 실패할 수 있습니다. (신청할 500MB는 연속 메모리이기 때문에, 매번 신청하는 메모리는 연속 메모리 공간이고, 여기서 1G는 여러 조각의 합일 수 있습니다.) , 그래서 이러한 문제는 실제로 프로그램 실행에 많은 영향을 미칩니다

      2.2. 복사 알고리즘Java 지식 요약 및 JVM에 대한 자세한 설명

      위의 mark-clear 전략은 메모리 조각화 문제를 일으킬 수 있으므로,

      이 문제를 해결하기 위해 복사 알고리즘이 도입되었습니다

      복사 알고리즘의 전략은 메모리의 절반을 사용하고 절반은 버리고 전부 사용하지 않는 것입니다. 일반적인 사용에서는 정크가 아닌 부분을 나머지 절반에 복사합니다(이 복사본). JVM에 의해 내부적으로 처리되므로 걱정하지 마세요) 이전에 사용한 메모리가 모두 해제되므로 메모리 조각화 문제가 해결됩니다.

      따라서 복사 알고리즘에는 두 가지 큰 문제가 있습니다.

      낮음 메모리 공간 활용(일반 메모리만 사용)
      Java 지식 요약 및 JVM에 대한 자세한 설명 보관할 개체가 많고 해제할 개체가 적을 경우 복사 비용이 매우 높아집니다.

      2.3.
        복사 알고리즘에 대한 또 다른 개선
      • !
      • 표시 및 정리 전략은
      가비지 않은 메모리를 함께 정리한 다음 이후의 메모리를 모두 해제

      하는 것입니다. 이는 중간 요소를 삭제하는 작업과 유사합니다.

      이 솔루션은 공간 활용도가 높지만 요소 복사/이동의 높은 오버헤드 문제를 해결할 방법이 없습니다.

      위의 세 가지 솔루션으로 문제를 해결할 수는 있지만 모두 고유한 단점이 있으므로 실제로 JVM의 구현은 여러 솔루션, 즉 "세대별 재활용"을 결합합니다!!!
      2.4 세대별 재활용Java 지식 요약 및 JVM에 대한 자세한 설명
      여기서의 세대는 객체를 분류하는 것입니다. 여기서 나이는 개체가 한 라운드 GC 스캐닝에서 살아남았다는 것을 의미하며 "1년 더 오래됨"이라고 합니다), 서로 다른 연령의 개체에 대해 서로 다른 계획이 채택됩니다!!!
      이것이 전체입니다 세대별 재활용 과정!

      3. 가비지 수집기

      위의 가비지 수집 및 가비지 릴리스는 실제 구현 프로세스가 아닌 알고리즘 아이디어일 뿐입니다. 위의 알고리즘 모듈을 실제로 구현하는 것은 "가비지 수집기"입니다.

      3.1. Serial Collector와 Serial Old Collector

      Serial Collector는 신세대를 위한 가비지 컬렉터이고, Serial Old Collector는 Old 세대를 위한 가비지 컬렉터입니다. 이 두 컬렉터는 순차적으로 수집되며, 가비지가 스캔되어 해제될 때 사용됩니다. , 비즈니스 스레드가 작동을 중지해야 하므로 스캔이 가득 차고 릴리스가 느려지며 심각한 STW가 생성될 수도 있습니다.

      3.2. ParNew 컬렉션 수집기, Parallel Scavenge 수집기 및 Parallel Old 수집기

      ParNew 수집기 Parallel Scavenge 컬렉터는 새로운 세대에 제공됩니다. Parallel Scavenge 컬렉터는 STW 시간을 제어할 수 있는 ParNew 컬렉터에 비해 몇 가지 매개 변수를 추가합니다. 즉, 더 강력한 기능을 갖춘 Parallel Old 컬렉터가 이전 세대에 제공됩니다. 수집기는 모두 병렬로 수집하며, 이는 가비지 스캔 및 가비지 해제 기능을 해결하기 위한 다중 스레드 접근 방식을 도입합니다!

      위 이 수집기는 역사에 남아 있으며, 이는 오래된 가비지 수집 방법입니다. 또한 두 가지 새로운 수집기를 소개합니다.

      3.3.CMS 수집기

      CMS 수집기의 원래 의도는 STW 시간을 최대한 짧게 만드는 것입니다. 여기에는 CMS 수집기에 대한 간략한 소개가 있습니다. CMS 수집기 프로세스:

        초기 표시: 속도가 매우 빠르며 짧은 STW가 발생합니다(그냥 Find GCRoots).
      1. 동시 표시: 매우 빠르지만 비즈니스 스레드와 동시에 실행될 수 있습니다. STW를 생성하지 않습니다.
      2. 주의: 2개의 비즈니스 코드가 동시 마킹 결과에 영향을 미칠 수 있으므로(비즈니스 스레드가 실행될 때 새로운 쓰레기가 생성될 수 있음) 이 단계에서는 2의 결과를 미세 조정합니다. STW가 발생하지만 미세 조정일 뿐이며 속도가 매우 빠릅니다.
      3. 위의 세 단계는 모두 도달 가능성 분석을 기반으로 합니다.
      4. 메모리 재활용: 또한 비즈니스 스레드는 동시에 실행되며 STW를 생성하지 않습니다.
      3.4.G1 컬렉터

      G1 컬렉터는

      유일한 전체 영역 가비지 컬렉터이며 G1은 Java11 Collector부터 사용되었으며 이 컬렉터는 전체 메모리를 여러 개의 작은 영역으로 나눕니다. 일부 지역은 신세대 개체를 넣고, 일부 지역은 구세대 개체를 넣습니다. 그런 다음 스캔할 때 한 번에 여러 지역을 스캔합니다(한 번의 GC에서 스캔을 완료하고 싶지 않고 여러 번 스캔해야 함).

      이 두 가지 새로운 수집기의 핵심 아이디어는 현재 STW 일시 중지 시간을 1ms 미만으로 최적화할 수 있다는 것입니다. !위는 JVM에 대한 학습입니다. 여기서 수집기는 주로 이해에 관한 것이며 위의 가비지 수집 아이디어는 매우 중요합니다!!!

      추천 학습: "

      java 비디오 튜토리얼"

    위 내용은 Java 지식 요약 및 JVM에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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