C++ 언어에서는 객체를 사용하려면 해당 객체에 대해 새 작업을 수행해야 하고, 객체를 더 이상 사용하지 않으면 해당 객체에 대해 삭제 작업을 수행해야 한다는 것을 알고 있습니다. 개발자가 삭제 문 작성을 잊어버리면 메모리 누수가 발생합니다. [객체가 메모리를 차지하고 반환되지 않는 경우를 메모리 누수라고 합니다. ]
그리고 Java는 "수동"에서 "자동"으로 진화했으며 메모리 제어권을 가상 머신에 넘겼습니다. jvm이 자동 메모리 관리를 수행하는 방법을 살펴보겠습니다.
자동 메모리 관리는 두 부분으로 나뉩니다:
객체에 메모리를 할당하고 객체에 할당된 메모리를 회수합니다. 이 기사에서는 전자인 메모리 분할과 메모리 할당에 대해 설명합니다. 다음 글에서는 GC(garbage collection)에 대해 이야기해보겠습니다.
1. 메모리 파티션
가상 머신 메모리에는 무엇이 있는지 살펴보겠습니다. JVM의 메모리 영역은 크게 클래스 파일, 클래스 로딩 서브시스템, 런타임 데이터 영역, 실행 엔진으로 나누어진다. 오늘 우리는 런타임 데이터 영역에 대해서만 이야기합니다. [이 그림은 JDK7을 기준으로 작성되었습니다. JDK7 이전에는 상수 풀이 메소드 영역에 저장되었습니다. JDK7부터 상수 풀은 힙에 배치되었습니다. 】
Thread public
런타임 데이터 영역에서 메소드 영역과 힙은 스레드에 공개됩니다. 즉, 이 두 영역은 "재활용"되므로 가비지 수집되어야 합니다. 가상 머신이 시작될 때 생성됩니다.
Thread private
가상 머신 스택, 로컬 메서드 스택 및 프로그램 카운터는 스레드와 함께 "살고 죽고" "일회성"이므로 필요하지 않습니다. 쓰레기가 수집되었습니다.
(1) 메소드 영역
클래스 정보, 상수, 정적 변수, JIT(Just-In-Time) 컴파일러로 컴파일된 코드 및 가상 머신에서 로드한 기타 데이터를 저장합니다.
런타임 상수 풀이 있습니다. 클래스 파일에 설명된 기호 참조, 직접 참조를 저장합니다. 컴파일 타임과 런타임 모두에 새로운 상수를 이 풀에 넣을 수 있습니다.
(2) 힙
개념: 스택이 프로그램 작동 문제, 즉 프로그램이 데이터를 처리하는 방법을 해결한다면 힙은 데이터 저장 문제, 즉 데이터 저장 방법과 위치를 해결합니다. 데이터를 넣어.
특징:
a. 힙은 가상 머신 메모리의 가장 큰 부분으로 메모리의 약 3/4을 차지합니다. 예를 들어, 32비트 Windows 플랫폼의 각 프로세스에 2GB의 메모리가 있는 경우 일반적으로 1.5GB의 메모리가 힙에 할당됩니다. 힙이 많은 공간을 차지하는 것을 볼 수 있습니다.
b. 논리적으로 연속적인 한 물리적으로 불연속적인 메모리 공간에 있을 수 있습니다.
기능:
Storage 개체 인스턴스, 거의 모든 개체 인스턴스가 여기에 메모리를 할당합니다.
분류:
메모리 재활용의 관점에서 보면 신세대와 구세대로 나누어집니다.
메모리 할당의 관점에서 여러 스레드 전용 할당 버퍼를 나눌 수 있습니다.
(3) 가상 머신 스택
가상 머신 스택에는 로컬 변수 테이블, 피연산자 스택, 동적 링크, 메소드 종료 및 기타 정보가 저장되는 스택 프레임이 저장됩니다.
스택의 스택 프레임
모든 메서드는 실행 중에 스택 프레임을 생성합니다. 메서드 호출부터 실행 완료까지의 프로세스는 스택 프레임이 가상 머신 스택에 들어가는 것과 같습니다. 스택에서 팝으로 가는 과정.
스택 프레임의 지역 변수 테이블
은 컴파일 타임에 알려진 다양한 기본 데이터 유형, 개체 참조 및 returnAddress 유형을 저장합니다. 따라서 필요한 메모리 공간은 컴파일 중에 할당될 수 있으며 그 크기는 런타임 중에 변경되지 않습니다.
기본 데이터 유형이 차지하는 공간을 할당할 때 64비트 long 및 double 유형 데이터를 제외하고 두 개의 지역 변수 공간을 차지하며 다른 데이터 유형은 하나만 차지합니다.
(4) 로컬 메소드 스택
로컬 메소드 스택과 가상 머신 스택의 기능은 동일하며, 가상이라는 점을 제외하면 머신 스택은 Java 메소드를 실행하고 로컬 메소드 스택은 기본 메소드를 실행합니다.
Java 메소드는 개발자가 작성한 Java 코드이고, Native 메소드는 Java가 Java가 아닌 코드를 호출하기 위한 인터페이스입니다.
(5) 프로그램 카운터
프로그램 카운터는 현재 스레드에서 실행된 바이트를 저장합니다. 코드의 번호입니다. jvm이 작동하면 이 카운터의 값을 변경하여 실행해야 하는 다음 바이트코드 명령을 선택합니다.
2. 메모리 할당
이 부분에서는 Java의 객체에 대해 이야기합니다. 힙 할당, 배치 및 액세스 방법과 메모리 할당 원칙입니다.
객체 생성
new를 사용하여 객체를 생성합니다. 살펴보겠습니다. 시스템에서 new를 실행할 때 가상 머신은 무엇을 하고 있나요? 이때 인간은 고기와도 같아서 인간의 식탁에 오르기 전에 여러 차례의 보안 검색을 거쳐야 합니다. 1단계: 상수 풀에 해당 기호 참조가 있는지 확인합니다. [메서드 영역에서 진행]
2단계: 이 클래스가 로드, 파싱 및 초기화되었는지 확인합니다. [메서드 영역에서 진행]
3단계: 새 객체의 메모리를 받습니다. 포인터 충돌과 자유 목록의 두 가지 방법이 있습니다. [힙에서 진행]
4단계: 할당된 메모리 공간을 0 값으로 초기화합니다.
5단계: 어떤 클래스가 인스턴스인지, 객체의 해시 코드 등 객체에 필요한 설정을 합니다. 이 정보는 객체의 객체 헤더에 저장됩니다
6단계: 객체에 Java 코드의 초기 값이 할당되면 6단계가 수행됩니다.
객체의 메모리 레이아웃
#🎜 🎜#메모리에 있는 객체의 저장 레이아웃은 객체 헤더 + 인스턴스 데이터 + 정렬 패딩의 세 부분으로 나뉩니다.
Object header
Object header 내부에는 두 부분의 정보가 있습니다: (1) 해시 코드, GC 생성 기간, 잠금 상태 플래그 등을 포함한 런타임 데이터. (2) 포인터를 입력하면 가상 머신은 이 포인터를 사용하여 이 객체가 어떤 클래스의 인스턴스인지 결정합니다. 인스턴스 데이터인스턴스 데이터는 코드에 정의된 다양한 유형의 필드 내용을 저장합니다. Alignment paddingAlignment padding은 자리 표시자 역할을 하며 반드시 존재하는 것은 아닙니다. 객체의 크기가 8바이트의 정수 배수인지 확인하기만 하면 됩니다.객체 액세스 위치 지정
객체를 생성한 후 객체를 사용할 수 있습니다. 그것을 사용할 때, 당신이 찾고 있는 물건을 어떻게 찾을 수 있습니까? 두 가지 방법이 있습니다: 핸들 및 직접 포인터
핸들:
핸들 액세스는 Java 힙의 메모리 조각을 핸들 풀로 나누는 것입니다. 핸들에는 객체 인스턴스 데이터의 특정 주소가 포함되어 있습니다. 데이터를 입력합니다.
직접 포인터:
직접 포인터가 "직접"인 이유는 핸들의 매개체를 제거하기 때문입니다. 그래서 핸들보다 빠릅니다. HotSpot 가상 머신에서는 이 방법이 사용됩니다.
Java 힙에서 객체가 할당, 배치 및 액세스되는 방법을 설명한 후 메모리 할당 원칙에 대해 이야기해 보겠습니다.
메모리 할당 원칙:
힙은 크게 신세대, 구세대, 영구세대로 구분됩니다. 객체의 메모리 할당은 주로 New Generation의 Eden 영역에 할당되며, Old Generation에 직접 할당되는 경우도 있습니다. 할당 규칙은 100% 고정되지 않으며 가비지 수집기 조합 및 매개변수 설정에 따라 달라집니다. 아래에는 몇 가지 참고할 수 있는 할당 원칙이 있습니다.
(1) 객체는 Eden에서 먼저 할당됩니다.
(2) 대형 물체는 노년기에 직접 들어갑니다.
(3) 장기 생존 개체는 Old Generation으로 들어갑니다.
(4) 동적 개체 연령 결정.
(5) 공간 할당 보장.
위 내용은 JAVA 가상 머신의 메모리 분할입니다. 더 궁금한 사항이 있으면 PHP 중국어 웹사이트를 방문하세요. JAVA 비디오 튜토리얼
위 내용은 JAVA Virtual Machine(JVM)(2)에 대한 자세한 설명 - 메모리 분할의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!