일반적으로 새로운 개체는 모두 힙에 할당 된 것으로 여겨지지만 완전히 정확하지는 않습니다. Java 객체 할당 프로세스의 분석을 통해 힙에 할당되는 것 외에도 물체가 스택 또는 TLAB에 공간을 할당 할 수도 있음을 발견했습니다. 스택에 물체를 할당하는 기술적 기반은 탈출 분석 및 스칼라 교체입니다. 이 기사는 주로 탈출 분석을 소개합니다.
탈출 분석의 정의
탈출 분석은 Java 프로그램의 동기 부하 및 메모리 힙 할당 압력을 효과적으로 줄일 수있는 교차 기능 글로벌 데이터 흐름 분석 알고리즘입니다.
탈출 분석을 통해 Java 핫스팟 컴파일러는 새로운 객체의 참조 사용 범위를 분석하고 힙에 객체를 할당할지 여부를 결정할 수 있습니다.
Java는 Java SE 6U23 및 이후 버전에서 탈출 분석 옵션을 지원하고 활성화합니다. Java의 핫스팟 JIT 컴파일러는 메소드가 과부하되거나 동적으로로드 될 때 코드의 탈출 분석을 수행 할 수 있습니다.
탈출 분석의 기본 동작은 객체의 동적 범위를 분석하는 것입니다. 객체가 메소드에서 정의되면 외부 방법으로 참조 할 수 있습니다.
메소드 탈출 : 예를 들어, 다른 메소드로 통화 매개 변수로 전달하십시오.
스레드 탈출 : 클래스 변수에 값을 할당하거나 다른 스레드에서 액세스 할 수있는 인스턴스 변수와 같은 외부 스레드에서 액세스 할 수 있습니다.
탈출 분석의 이론적 기초
탈출 분석은 Jong-Deok Choi, Manish Gupta, Mauricio Seffano, Vugramam C. Sreedhar, Sam Midkiff 등이 설명한 알고리즘을 기반으로 수행됩니다.
이 알고리즘은 연결된 그래프를 소개하고 연결된 그래프를 사용하여 객체와 객체 참조 사이의 접근 가능한 관계를 구성하며,이를 바탕으로 결합 된 데이터 흐름 분석 방법이 제안됩니다. 알고리즘은 컨텍스트 의존적이고 스트림에 민감하고 객체의 모든 수준에서 중첩 관계를 시뮬레이션하기 때문에 분석 정확도는 높지만 실행 시간과 메모리 소비는 비교적 큽니다.
탈출 분석의 대부분의 구현은 "폐쇄 세계"의 전제를 기반으로합니다. 실행되는 모든 가능한 방법은 탈출 분석 전에 알려져 있으며 실제 운영은 프로그램 간의 통화 관계를 변경하지 않습니다. 그러나 실제 Java 프로그램이 실행되면 그러한 가정은 사실이 아닙니다. 다이나믹 클래스 로딩, 로컬 기능 호출 및 프로그램 통화 반영과 같은 Java 프로그램의 많은 기능은 소위 "폐쇄 된 세계"컨벤션을 중단 할 것입니다.
탈출 분석 후 처리 작업
탈출 분석 후, 객체의 3 가지 가능한 탈출 상태를 얻을 수 있습니다.
GlobalEScape : 즉, 객체의 참조는 메소드 나 스레드를 빠져 나옵니다. 예를 들어, 객체의 참조는 클래스 변수에 복사되거나 탈출 한 객체에 저장되거나 객체의 참조가 메소드의 리턴 값으로 호출 메소드로 반환됩니다.
ARGESCAPE (매개 변수 레벨 탈출) : 즉, 메소드 호출 프로세스 중에 객체의 적용이 메소드로 전달되었습니다. 이 상태는 조정되는 방법의 이진 코드를 분석하여 결정할 수 있습니다.
Noescape : 스칼라로 교체 할 수있는 물체. 객체는 전통적인 힙에 할당되지 않을 수 있습니다.
컴파일러는 탈출 분석 결과를 사용하여 프로그램을 최적화 할 수 있습니다.
힙 할당 객체는 스택 할당 객체가됩니다. 메소드의 객체가되고 객체 참조가 탈출되지 않으므로이 방법은 스택 메모리에 할당 될 수 있으며 힙 메모리에 매우 일반적입니다.
동기화 제거 : 스레드 동기화 비용이 상당히 높으며 동기화의 결과는 동시성과 성능이 줄어 듭니다. 탈출 분석은 객체가 항상 하나의 스레드 만 액세스되는지 여부를 결정할 수 있습니다. 하나의 스레드만으로 액세스하면 객체의 동기화 작업을 동기화 보호없이 작업으로 변환 할 수 있으며 동시성 및 성능의 정도를 크게 향상시킬 수 있습니다.
벡터 대체 : 탈출 분석 방법 객체의 메모리 저장 구조를 지속적으로 수행 할 필요가 없다면 CPU 레지스터의 부품 및 모든 물체를 저장할 수있어 액세스 속도를 크게 향상시킬 수 있습니다.