>Java >Java베이스 >그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명

尚
앞으로
2019-11-30 16:27:262353검색

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명

1. 개요

멀티태스킹과 높은 동시성은 컴퓨터 프로세서의 성능을 측정하는 중요한 지표 중 하나입니다. 일반적으로 서버의 성능을 측정하려면 TPS(초당 트랜잭션) 표시기가 더 적합합니다. 이는 서버가 1초에 응답할 수 있는 평균 요청 수를 나타내며 TPS 값은 프로그램의 동시성 기능과 관련됩니다. 매우 밀접한 관련이 있습니다. Java 메모리 모델과 스레드에 대해 논의하기 전에 하드웨어의 효율성과 일관성에 대해 간략하게 소개하겠습니다. (권장: java 비디오 튜토리얼)

2. 하드웨어 효율성 및 일관성

컴퓨터의 저장 장치와 프로세서의 컴퓨팅 성능 사이에는 몇 배의 차이가 있기 때문에 현대 컴퓨터 시스템은 읽기 및 쓰기 속도가 프로세서의 작업 속도에 최대한 가까운 캐시(캐시) 계층을 메모리와 프로세서 사이의 버퍼로 추가해야 합니다. 작업에 필요한 데이터가 캐시에 복사되므로 작업이 완료되면 프로세서가 느린 메모리 읽기 및 쓰기를 기다릴 필요가 없도록 캐시에서 메모리로 다시 동기화됩니다.

캐시 기반 저장소 상호 작용은 프로세서와 메모리 간의 속도 충돌을 매우 잘 해결하지만 캐시 일관성이라는 새로운 문제를 야기합니다. 다중 프로세서 시스템에서 각 프로세서는 자체 캐시를 가지며 동일한 주 메모리를 공유합니다.

아래 그림과 같이 여러 프로세서 컴퓨팅 작업에는 동일한 메인 메모리가 포함되며 데이터 일관성을 보장하려면 프로토콜이 필요합니다. 이러한 프로토콜에는 MSI, MESI, MOSI 및 Dragon Protocol 등이 포함됩니다. Java 가상 머신 메모리 모델에 정의된 메모리 액세스 작업은 나중에 소개할 하드웨어 캐시 액세스 작업과 유사합니다.

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명

또한 프로세서 내부의 컴퓨팅 장치를 최대한 활용하기 위해 프로세서는 입력 코드에 대해 Out-Of-Order Execution 최적화를 수행할 수 있습니다. 계산 후 코드 실행 결과가 출력됩니다. 결과의 정확성을 보장하기 위해 순서가 재구성됩니다. 프로세서의 비순차 실행 최적화와 유사하게 Java 가상 머신의 JIT(Just-In-Time) 컴파일러도 유사한 명령어 재정렬(명령어 레코더) 최적화를 갖습니다.

3. Java 메모리 모델

Java 메모리 모델을 정의하는 것은 쉬운 작업이 아닙니다. 이 모델은 Java의 동시 작업이 모호성을 유발하지 않도록 충분히 엄격하게 정의되어야 합니다. 가상 머신의 구현에는 더 나은 실행 속도를 얻기 위해 하드웨어의 다양한 기능(레지스터, 캐시 등)을 활용할 수 있는 충분한 여유 공간이 있어야 합니다. 오랜 기간의 검증과 패치를 통해 Java 메모리 모델은 JDK1.5 출시 이후 성숙해지고 개선되었습니다.

3.1 주 메모리 및 작업 메모리

Java 메모리 모델의 주요 목표는 프로그램의 각 변수에 대한 액세스 규칙, 즉 변수를 메모리에 저장하고 메모리에서 변수를 검색하는 하위 수준 세부 정보를 정의하는 것입니다. 가상 머신의 메모리. 여기의 변수는 Java 프로그래밍에서 언급된 변수와 다릅니다. 여기에는 인스턴스 필드, 정적 필드 및 배열 객체를 구성하는 요소가 포함되지만 로컬 변수 및 메소드 매개변수는 포함되지 않습니다. .

Java 메모리 모델은 모든 변수가 주 메모리에 저장된다고 규정합니다. 각 스레드에는 자체 작업 메모리(이전 프로세서의 캐시와 비교 가능)가 있으며 스레드의 작업 메모리에는 사용된 변수가 저장됩니다. 스레드에 의한 변수의 모든 작업(읽기, 할당)은 작업 메모리에서 수행되어야 하며, 메인 메모리에 있는 변수는 직접 읽고 쓸 수 없습니다.

서로 다른 스레드는 서로의 작업 메모리에 있는 변수에 직접 접근할 수 없습니다. 스레드 간 변수 값의 전송은 메인 메모리에서 완료되어야 합니다. 스레드와 메인 메모리, 작업 메모리 간의 상호 관계는 아래 그림과 같습니다. , 이는 위의 그림과 매우 유사합니다.

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명

여기서 메인 메모리, 작업 메모리와 자바 메모리 영역의 자바 힙, 스택, 메소드 영역은 동일한 수준의 메모리 분할이 아닙니다.

3.2 메모리 간 상호 작용

메인 메모리와 작업 메모리 사이의 특정 상호 작용 프로토콜, 즉 변수가 메인 메모리에서 작업 메모리로 복사되는 방법과 작업 메모리에서 메인으로 동기화하는 방법에 대한 구현 세부 사항 메모리, Java 메모리 모델은 완료할 다음과 같은 8가지 작업을 정의합니다.

1. 잠금: 주 메모리의 변수에 작용하여 변수를 스레드 전용으로 표시합니다.

2. 잠금 해제: 잠금 상태의 변수를 해제하기 위해 메인 메모리 변수에 작용합니다. 해제된 변수만 다른 스레드에 의해 잠길 수 있습니다.

3. 읽기: 주 메모리 변수에 작용하여 주 메모리에서 스레드의 작업 메모리로 변수 값을 전송하여 후속 로드 작업에서 사용할 수 있도록 합니다.

4. 로드: 작업 메모리의 변수에 대해 읽기 작업을 통해 주 메모리에서 얻은 변수 값을 작업 메모리의 변수 복사본에 넣습니다.

5. 사용: 작업 메모리의 변수에 작용하여 작업 메모리의 변수 값을 실행 엔진에 전달합니다. 이는 가상 머신이 변수 값이 필요한 바이트코드 명령어를 발견할 때마다 실행됩니다.

6. 할당(할당): 실행 엔진에서 받은 값을 작업 메모리의 변수에 할당합니다. 이는 가상 머신이 값을 할당하는 바이트코드 명령을 만날 때마다 실행됩니다. 변수로 작동합니다.

7. 저장(storage): 작업 메모리의 변수에 작용하여 후속 쓰기 작업을 위해 작업 메모리의 변수 값을 주 메모리로 전송합니다.

8. 쓰기: 주 메모리의 변수에 대해 작업 메모리의 변수 값에서 주 메모리의 변수로 저장 작업을 전송합니다.

주 메모리에서 작업 메모리로 변수를 복사하려면 읽기 및 로드 작업을 순서대로 수행해야 합니다. 작업 메모리에서 다시 주 메모리로 변수를 동기화하려면 다음을 수행해야 합니다. 저장 및 쓰기 작업을 순차적으로 수행합니다.

Java 메모리 모델에서는 위의 작업이 순서대로 실행되어야만 할 뿐 지속적으로 실행되어야 한다는 보장은 없습니다. 즉, 읽기와 로드 사이, 저장과 쓰기 사이에 다른 명령을 삽입할 수 있습니다. 예를 들어 주 메모리의 변수 a와 b에 액세스할 때 가능한 순서는 읽기 a, 읽기 b, 로드 b, 로드 a입니다. 또한 Java 메모리 모델에서는 위의 8가지 기본 작업을 수행할 때 다음 규칙을 충족해야 한다고 규정합니다.

1. 읽기, 로드, 저장 및 쓰기 작업 중 하나가 단독으로 나타날 수 없습니다.

2. 스레드는 최신 할당 작업을 버릴 수 없습니다. 즉, 변수는 작업 메모리에서 변경된 후 주 메모리와 동기화되어야 합니다.

3. 스레드는 이유 없이 작업 메모리의 데이터를 기본 메모리로 다시 동기화할 수 없습니다(할당 작업이 발생하지 않음).

4. 새로운 변수는 메인 메모리에서만 생성될 수 있으며, 초기화되지 않은(로드 또는 할당) 변수는 작업 메모리에서 직접 사용할 수 없습니다. 즉, 변수에 대한 사용 및 저장 작업을 수행하기 전에 할당 및 로드 작업을 먼저 수행해야 합니다.

5. 하나의 스레드만 동시에 변수를 잠글 수 있습니다. 잠금 및 잠금 해제는 쌍으로 나타나야 합니다.

6. 변수에 대해 잠금 작업이 수행되면 작업 메모리에 있는 이 변수의 값은 다음과 같습니다. 실행 엔진이 이 변수를 사용하기 전에 변수 값을 초기화하기 위해 로드 또는 할당 작업을 다시 실행해야 합니다

7. 변수가 잠금 작업으로 미리 잠기지 않은 경우에는 허용되지 않습니다. 잠금 해제 작업을 수행하려면 다른 스레드 변수에 의해 잠긴 변수를 잠금 해제할 수도 없습니다.

8. 변수에 대한 잠금 해제 작업을 수행하기 전에 변수를 주 메모리에 동기화해야 합니다(저장 및 쓰기 작업 수행).

3.3 재정렬

프로그램 실행 시 성능을 향상시키기 위해 컴파일러와 프로세서에서는 명령어를 재정렬하는 경우가 많습니다. 재정렬은 세 가지 유형으로 나뉩니다.

1. 컴파일러에 최적화된 재정렬. 컴파일러는 단일 스레드 프로그램의 의미를 변경하지 않고도 문의 실행 순서를 다시 정렬할 수 있습니다.

2. 명령어 수준 병렬 재정렬. 최신 프로세서는 명령어 수준 병렬성을 사용하여 여러 명령어의 실행을 중첩합니다. 데이터 종속성이 없으면 프로세서는 명령문이 기계 명령에 해당하는 순서를 변경할 수 있습니다.

3. 메모리 시스템 재정렬. 프로세서는 캐시와 읽기 및 쓰기 버퍼를 사용하기 때문에 로드 및 저장 작업이 순서 없이 실행되는 것처럼 보일 수 있습니다.

Java 소스 코드부터 실제로 실행된 최종 명령어 시퀀스까지 다음 세 가지 재정렬을 거칩니다.

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명메모리 가시성을 보장하기 위해 Java 컴파일러는 생성된 명령어 시퀀스의 적절한 위치에 메모리 장벽 명령어를 삽입합니다. 특정 유형의 프로세서 재주문을 금지합니다. Java 메모리 모델은 메모리 장벽을 LoadLoad, LoadStore, StoreLoad 및 StoreStore의 네 가지 유형으로 나눕니다.

그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명자바에 대한 자세한 내용은 java 기본 튜토리얼 칼럼을 참고하세요.

위 내용은 그림과 텍스트로 Java 메모리 모델에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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