>  기사  >  Java  >  JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

不言
不言앞으로
2018-10-16 17:02:123617검색

이 글은 JVM 메모리 모델과 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)을 제공합니다. 필요한 친구들이 참고할 수 있기를 바랍니다.

1. Java 메모리 모델

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

# 🎜🎜#java 메모리 모델을 정의하는 목적은 다양한 하드웨어와 운영 체제의 메모리 액세스 간의 차이를 보호하는 것입니다.

Java 메모리 모델은 모든 변수가 메인 메모리에 저장되고, 각 스레드는 자체 작업 메모리를 가지며, 작업 메모리는 변수의 복사본을 메인 메모리에 저장한다고 규정합니다.

변수에 대한 스레드 연산은 작업 메모리에서만 수행할 수 있으며, 주 메모리에서 변수를 직접 읽거나 쓸 수는 없습니다.

서로 다른 스레드 간의 가변 액세스는 메인 메모리를 통해 완료되어야 합니다.

1. Java 메모리 모델과 Java 런타임 데이터 영역의 관계: 메인 메모리는 Java 힙에 해당하고 작업 메모리는 Java 스택에 해당합니다.

2. 휘발성 키워드는 각 작업 메모리에서 변수 업데이트를 실시간으로 표시합니다. DCL의 싱글톤 모드에서는

을 사용합니다. 2. Java 런타임 데이터 영역/메모리 영역

때문에. 이 영역은 지속적으로 개선되고 있으므로 JDK 버전에 따라 차이가 있을 수 있습니다.

1. jdk1.7 이전의 jvm 메모리 영역에는 영구 세대가 있습니다. 1. 프로그램 카운터의 역할은 .java 파일이 .class 파일로 컴파일되기 때문에 현재 스레드에서 실행되는 바이트코드에 대한 줄 번호 표시기 역할을 합니다. 바이트코드 해석기가 작동하면 이 계산기의 값을 변경하여 실행할 다음 바이트코드 명령어를 선택합니다. 각 스레드에는 독립적인 프로그램 카운터가 있습니다.

2. 로컬 메서드 스택은 로컬 네이티브 메서드를 실행하는 스택입니다. JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)3. 자바 가상 머신 스택은 스레드가 자바 메소드(method)를 실행할 때의 메모리 모델을 기술합니다. 각 메소드는 스택 프레임에 해당하며 스택 프레임의 지역 변수 테이블에는 메소드의 기본 데이터 유형 변수와 객체 참조 변수가 저장됩니다.

위 그림과 같이 로컬 변수 테이블에는 8개의 기본 타입 변수와 선언된 객체 참조가 저장되어 있습니다. 메소드 변수. 각 스택 프레임에는 String 유형을 참조하는 런타임 상수 풀에 대한 참조도 있습니다.

다음은 고전적인 문자열 객체 생성 인터뷰 질문입니다!

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)4. Java 힙은 JVM에서 가장 큰 메모리 조각이며 모든 스레드에서 공유됩니다. 거의 모든 객체 인스턴스가 여기에 할당되므로 Java 힙은 JVM 가비지 수집의 주요 영역이기도 합니다.

자바 힙은 Young 세대와 Old 세대로 구분되며, Young 세대는 다시 Eden 공간, From Survivor 공간, To Survivor 공간으로 나눌 수 있습니다.

new 키워드를 사용하여 객체를 할당하면 객체가 Java 힙에 생성됩니다.

객체가 생성되는 상황을 분석해 보겠습니다. JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

Eden이 가장 크기 때문에 새로 생성된 객체는 Eden 공간이 거의 가득 차면 Minor GC를 수행한 후 살아남습니다. 개체는 생존자 공간으로 복사됩니다. 이때 Eden 공간은 계속해서 외부에 힙 메모리를 제공한다.

나중에 생성될 객체는 여전히 Eden 공간에 배치됩니다. 이때 Eden 공간과 From Survivor는 다시 채워집니다. 공간은 동시에 Minor GC를 수행합니다. 그런 다음 살아남은 개체를 To Survivor 공간에 넣습니다. 이때 Eden 공간은 계속해서 외부에 힙 메모리를 제공한다.
  1. 다음 상황은 2와 일치합니다. Eden 공간이 거의 가득 차면 Eden 공간과 To Survivor 공간에서 Minor GC를 수행한 후 살아남은 객체를 From Survivor 공간에 배치합니다.
  2. 다음 상황은 3과 일치합니다. Eden 공간이 빠르거나 느린 경우 Eden 공간과 From Survivor 공간은 Minor GC를 수행한 후 살아남은 객체를 To Survivor 공간에 배치합니다.
  3. 즉, 두 생존자 중 하나가 개체 저장소를 제공하는 데 사용됩니다.
  4. Eden 공간과 특정 Survivor 공간이 GC되고 다른 Survivor 공간이 GC에서 살아남은 개체를 보유할 수 없거나 약 15번의 연속 Minor GC가 발생하는 경우; 구세대 공간.

  5. Old Generation 공간도 가득 차면 Old Generation 공간을 재활용하기 위해 Major GC를 수행합니다. (

    은 Full GC이라고도 하며, Full GC는 메모리를 많이 소모하므로 피해야 합니다)

젊은 세대는 복사 알고리즘을 사용합니다. 즉, Minor GC가 Eden 영역과 Survivor 영역에서 살아남은 개체를 다른 Survivor 영역에 복사할 때마다. 이전 세대는 표시 보완 알고리즘을 사용합니다. 메이저 GC가 살아남은 개체를 메모리 공간의 한쪽 끝으로 이동할 때마다 끝 경계 외부의 메모리를 직접 정리합니다.

배열이나 매우 긴 문자열과 같은 큰 객체는 Old Generation 공간에 직접 들어갑니다.

5. 메소드 영역은 JVM에서 로드한 클래스 정보, 최종 상수, 정적 변수와 같은 데이터를 저장하는 데 사용됩니다. 메소드 영역에는 컴파일 중에 생성된 리터럴 및 기호 참조(클래스가 로드된 후에 배치됨)를 주로 저장하는 런타임 상수 풀도 포함되어 있습니다. String 개체의 리터럴 값은 런타임 상수 풀에 저장됩니다.

메서드 영역의 가비지 수집은 주로 상수 재활용과 유형 언로드를 포함합니다.

2jdk1.8 이상의 jvm 메모리 영역에서는 메타스페이스가 영구 세대를 대체합니다.

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

메타 공간과 영구 세대의 속성은 동일하며 둘 다입니다. JVM 메소드 영역의 구현도 동일합니다. 그러나 메타공간과 영구 생성의 가장 큰 차이점은 메타공간이 가상 머신 JVM 메모리에 있지 않고 로컬 메모리를 사용한다는 점이다.

영구 생성 대신 메타공간을 사용하는 이유는 무엇인가요?

  1. 문자열은 영구 생성에 저장되므로 성능 문제와 메모리 오버플로가 발생하기 쉽습니다.

  2. 클래스 및 메소드 정보의 크기를 결정하기 어렵기 때문에 영구 생성의 크기를 지정하기가 어렵습니다. 너무 작으면 영구 생성 오버플로가 발생하기 쉽고, 너무 크면 발생합니다. , 이는 쉽게 구세대가 넘쳐나게 할 것입니다.

  3. 영구 세대는 GC에 불필요한 복잡성을 가져오고 재활용 효율성이 낮습니다.

직접 메모리

JDK1.4 이후에 추가된 NIO는 채널 채널 및 버퍼 버퍼 기반 IO를 도입하고 네이티브 기능을 직접 사용하여 오프 힙 메모리를 할당함으로써 IO 성능을 크게 향상시키고 원본 BIO 복사 데이터가 필요하지 않게 합니다. Java 힙과 Naive 힙 사이를 왔다 갔다 합니다.

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

3. 문자열 생성 시 메모리 할당

참고 기사: Java의 문자열 상수 풀에 대한 자세한 설명.

4. 객체 생성 시 메모리 상황

객체 또는 기본 데이터 유형 변수 생성을 위한 일반적인 메모리 모델을 분석해 보겠습니다. 이를 통해 JVM을 더 잘 이해할 수 있습니다.

int i =3;, 메소드는 스택 프레임에 해당하며 메소드의 기본 데이터 유형 변수는 스택 프레임에 직접 할당됩니다. 정적 또는 최종 기본 데이터 유형인 경우 String과 마찬가지로 런타임 상수 풀에 저장됩니다.

Object o1 = new Object();, 객체 참조(Object o1)는 스택 프레임에 저장되지만 객체 데이터(new Object())는 Java 힙에 저장되고 객체 유형 데이터(Class 및 기타 정보)은 메소드 영역 중간에 저장됩니다.

String s1 = new String("abcd");, new로 선언된 객체를 사용하고, 객체 참조(String s1)는 스택 프레임에 저장되고, 객체 데이터(new String("abcd"))는 Java 힙, 문자 문자열 값("abcd")은 런타임 상수 풀에 저장됩니다.

String s2 = "abc", 객체 참조(String s2)는 스택 프레임에 저장되고 문자열 값("abc")은 런타임 상수 풀에 저장됩니다.

JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)

Java 스택, Java 힙, 메소드 영역의 관계는 대략 위의 분석과 같습니다.

3. 다양한 예외 분석

1. Java 힙 메모리 오버플로 오류 OutOfMemoryError

Java 힙에 너무 많은 개체가 할당되어 있고 GC 이후에도 메모리 공간이 부족한 경우. 다음 테스트는 메모리 공간을 소비하기 위해 객체를 주기적으로 생성하여 수행됩니다.

관련 지침: VM Args: -Xms20m -Xmx40m, JVM에서 할당한 최소 힙 메모리가 20MB이고 최대 힙 메모리가 40MB임을 나타냅니다. VM Args: -Xms20m -Xmx40m,表示JVM分配的堆内存最小为20MB,最大为40MB。

 public static void main(String[] args) {
   while (true) {
     List<object> list = new ArrayList(10);
     list.add(new Object());
   }
 }</object>

2、java栈堆栈溢出错误StackoverflowError

如果java栈的栈深度大于JVM允许的深度,就会抛出该错误。下面通过无限递归调用来进行堆栈进行测试。

相关指令:VM Args: -Xss128k

public class StackOOM {
    
    private int length = 1;
    
    public void stackLeak() {
        length++;
        stackLeak();
    }
    
    public static void main(String[] args) {
        StackOOM stackOOM = new StackOOM();
        stackOOM.stackLeak();
    }
}

2.java 스택 스택 오버플로 오류 StackoverflowErrorJVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)Java 스택의 스택 깊이가 JVM에서 허용하는 깊이보다 크면 이 오류가 발생합니다. 다음은 무한 재귀 호출을 통한 스택 테스트이다.

관련 지침: VM Args: -Xss128k, JVM에서 할당한 스택 용량이 128KB임을 나타냅니다.
rrreee

🎜🎜🎜🎜🎜🎜🎜

위 내용은 JVM 메모리 모델 및 런타임 데이터 영역에 대한 자세한 설명(그림 및 텍스트)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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