이 글에서는 주로 Java 프로그램 실행 시 메모리 분배에 대한 자세한 설명을 소개합니다. 필요한 친구들은
Java 메모리 분배를 참고하세요. 관리는 메서드 영역, 가상 머신 스택, 로컬 메서드 스택, 힙 및 프로그램 카운터 등 여러 가지 데이터 영역으로 구분됩니다.
1. 프로그램 카운터
프로그램 카운터는 현재 스레드가 실행하는 바이트코드의 줄 번호 표시라고 볼 수 있습니다. 가상 머신의 개념적 모델에서 바이트코드 인터프리터는 실행해야 하는 바이트코드 명령을 선택하기 위해 이 카운터의 값을 변경하여 작동합니다.
분기, 루프, 점프, 예외 처리 및 스레드 복구와 같은 기본 기능은 모두 이 카운터를 사용하여 완료됩니다.
스레드 전환 후 올바른 실행 위치로 복귀하기 위해서는 각 스레드마다 독립적인 프로그램 카운터가 있어야 하며, 각 스레드 간의 카운터는 서로 영향을 주지 않고 독립적으로 저장되므로 이러한 메모리 영역은 다음과 같습니다. "스레드 전용" 메모리입니다.
스레드가 Java 메소드를 실행하는 경우 이 카운터는 실행 중인 가상 머신 바이트코드 명령의 주소를 기록합니다. 스레드가 기본 메소드를 실행하는 경우 카운터 값은 비어 있으며 이 메모리는 Java Virtual Machine 사양이 OutOfMemoryError 조건을 지정하지 않는 유일한 영역입니다.
2. Java 가상 머신 스택
프로그램 카운터와 마찬가지로 Java 가상 머신 스택도 스레드 전용이며 수명 주기는 스레드. 가상 머신 스택은 Java 메소드 실행의 메모리 모델을 설명하며, 각 메소드가 실행될 때 로컬 변수 테이블, 피연산자 스택, 동적 링크, 메소드 종료 등과 같은 정보를 저장하기 위해 스택 프레임이 생성됩니다.
각 방법은 호출부터 실행 완료까지 스택 프레임이 가상 머신 스택 안팎으로 푸시되는 프로세스에 해당합니다.
지역 변수 테이블에는 다양한 기본 데이터 유형, 객체 참조(객체와 동일하지 않지만 객체에 대한 참조) 및 컴파일 타임에 알려진 returnAddress 유형이 저장됩니다. 스레드에서 요청한 스택 깊이가 가상 머신에서 허용하는 깊이보다 크면 StackOverflowError 예외가 발생합니다. 충분한 메모리를 적용할 수 없으면 OutOfMemory 예외가 발생합니다.
3. 로컬 메소드 스택
로컬 메소드 스택과 가상 머신 스택의 차이점은 가상 머신 스택이 가상 머신, 로컬 메서드 스택은 가상 머신에서 사용하는 기본 메서드를 제공합니다.
4. Java 힙
Java 힙은 모든 스레드가 공유하는 메모리 영역으로 가상 머신이 시작될 때 생성됩니다. 이 메모리 영역의 유일한 목적은 객체 인스턴스를 저장하는 것입니다. Java 힙은 가비지 컬렉터가 관리하는 주요 영역입니다
5. 메소드 영역
Java 힙과 동일하며, 각 스레드가 공유하는 메모리 영역으로 JIT 컴파일러에서 컴파일된 코드, 클래스 정보, 상수, 코드 등이 Load되어 있는 데이터를 저장하는 데 사용됩니다. 가상 머신.
6. 런타임 상수 풀
런타임 상수 풀은 메소드 영역의 일부입니다. 클래스 버전, 필드, 메소드, 인터페이스 등에 대한 설명 정보 외에도 클래스 파일에는 컴파일 중에 생성된 다양한 리터럴 및 기호 참조를 저장하는 데 사용되는 상수 풀이 있습니다. 그런 다음 메서드 영역의 런타임 상수 풀에 저장됩니다.
인터넷의 상수 풀에 대한 많은 설명은 문자열을 예로 사용합니다.
예를 들어,
String s1 = "Hello"; String s2 = "Hello"; String s3 = "Hel" + "lo"; String s4 = "Hel" + new String("lo"); String s5 = new String("Hello"); String s6 = s5.intern(); String s7 = "H"; String s8 = "ello"; String s9 = s7 + s8; System.out.println(s1 == s2); // true System.out.println(s1 == s3); // true System.out.println(s1 == s4); // false System.out.println(s1 == s9); // false System.out.println(s4 == s5); // false System.out.println(s1 == s6); // true
s1==s2는 true입니다. 이해하기 쉽고 동일한 상수 풀의 메모리 주소를 가리킵니다.
s1==s3은 true입니다. s3의 경우 모든 연결이 리터럴이므로 컴파일러가 최적화합니다. 이는 실제로 s3="Hello"
s1== s4가 false임을 의미합니다. new이므로 String("lo")은 리터럴이 아니지만 변수이므로 변수가 변경될 수 있으므로 컴파일러는 최적화하지 않습니다.
s1==s9는 false입니다. 위와 동일합니다.
s4==s5: 서로 다른 두 개체의 참조는 물론 다릅니다.
s1==s6: String.intern() 메소드는 다음을 의미합니다. 상수 풀에 이미 이 String 객체와 동일한 문자열이 포함되어 있는 경우(객체는 같음으로 표시됨) (Object ) 메소드가 결정), 풀의 문자열이 반환됩니다. 그렇지 않으면 이 String 개체가 풀에 추가되고 이 String 개체에 대한 참조가 반환됩니다. 임의의 두 문자열 s와 t에 대해 s.intern() == t.intern()은 s.equals(t)가 참인 경우에만 참입니다.
위 내용은 Java 메모리 배포 요약 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!