JVM에 대한 기본 지식-++ i와 i ++의 차이점을 이해하려면 바이트 코드 파일을 참조하십시오. String str = "11"이 두 OOP를 생성하는 방법을 보려면 메모리를 사용하십시오.

1. 클래스로드 방법

여기에 사진 설명 삽입

.1.1 java 파일 javac는 바이트 코드 명령어 세트 파일로 컴파일되며 javap -c Test.class는 관련 바이트 코드 명령어를 볼 수 있습니다.
1.2 클래스 로딩 서브 시스템은 클래스 파일을 InstanceKlass 메타 데이터로 구문 분석하여 메서드 영역에 넣습니다
.1.3 JDK8 이후 이전 세대 메타 스페이스가 취소되고 이전 세대로 대체됩니다 .1.4
메서드 영역은 인터페이스 이전 세대 메타 스페이스 로 이해 될 수 있습니다.
1.5 메소드 구현 영역 힙은 공유 메모리 영역이며 메소드 영역은 주로 클래스 메타 데이터, 상수 풀, 정적 변수 등을 포함하고 객체는 힙에 저장되며 로컬 메소드 스택은 확장 된 로컬 메소드입니다. 가상 머신 stack은 스택 프레임입니다. 메소드는 실행 후 Release가 실행되고 생성되는 스택 프레임입니다.

2. 가상 머신 스택 작업 ++ i 및 i ++

2.1 가상 머신 스택 내부에 대해 살펴 보겠습니다.
여기에 사진 설명 삽입
2.11 로컬 변수 테이블 : 주로 매개 변수 데이터, 로컬 변수 데이터를 저장합니다.
2.12 피연산자 스택 : LIFO 후입 선출 스택. 메소드 실행 중에 다양한 바이트 코드 명령어 피연산자 스택은 데이터, 즉 스택 및 팝 작업을 쓰거나 추출합니다.
2.13 동적 연결 : 스택 프레임이 상수 풀에 속하는 메소드에 대한 참조이 참조는 메소드 호출 중에 동적 연결을 지원하는 데 사용됩니다. 클래스 파일의 상수 풀에는 많은 수의 기호 참조가 있으며 바이트 코드 명령어는 상수 풀의 기호 참조를 매개 변수로 사용합니다. 심볼 참조는 정적 분석이라고하는 스테이지에서 사용될 때 직접 참조로 변환됩니다.
2.14 반환 주소 : 종료하는 두 가지 주요 방법이 있습니다. 하나는 일반적으로 바이트 코드 명령이 푸시되는 곳이고 다른 하나는 비정상적인 상황이 비정상적인 곳입니다. 종료의 종류에 관계없이 이전 메서드 호출의 PC 카운터 위치를 알아야합니다.

3. ++ i 및 i ++는 지역 변수 테이블과 피연산자 스택을 이해합니다.

public static void main(String[] args) {
    
    
	a();
	b();
}

public static void a() {
    
    
	int i = 5;
	int j = i++;
	System.out.println(j);
}

public static void b() {
    
    
	int i = 6;
	int j = ++i;
	System.out.println(j);
}

-- 输出结果如下:
Connected to the target VM, address: '127.0.0.1:62076', transport: 'socket'
5
6
Disconnected from the target VM, address: '127.0.0.1:62076', transport: 'socket'

3.1 바이트 코드

 // access flags 0x9
 public static a()V
	L0
	 LINENUMBER 11 L0
	 // int类型5 压入栈
	 ICONST_5
	 // index为0 保存到局部变量表
	 ISTORE 0
	L1
	 LINENUMBER 12 L1
	 // index为0 从局部变量表压到栈
	 ILOAD 0
	 // 通过常量增加局部变量
	 IINC 0 1
	 // index为1 保存到局部变量表
	 ISTORE 1
	L2
	 LINENUMBER 13 L2
	 GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
	 ILOAD 1
	 INVOKEVIRTUAL java/io/PrintStream.println (I)V
	L3
	 LINENUMBER 14 L3
	 RETURN
	L4
	 LOCALVARIABLE i I L1 L4 0
	 LOCALVARIABLE j I L2 L4 1
	 MAXSTACK = 2
	 MAXLOCALS = 2
 

 // access flags 0x9
 public static b()V
  L0
   LINENUMBER 17 L0
   // 将int型5 压入栈
   ICONST_5
   // index为0 保存至本地变量
   ISTORE 0
  L1
   LINENUMBER 18 L1
   // 通过常量增加局部变量
   IINC 0 1
   // 本地变量int型 index为0 读取到栈顶
   ILOAD 0
   // 将index为1 保存至本地变量
   ISTORE 1
  L2
   LINENUMBER 19 L2
   GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
   ILOAD 1
   INVOKEVIRTUAL java/io/PrintStream.println (I)V
  L3
   LINENUMBER 20 L3
   RETURN
  L4
   LOCALVARIABLE i I L1 L4 0
   LOCALVARIABLE j I L2 L4 1
   MAXSTACK = 2
   MAXLOCALS = 2

a 메소드의 바이트 코드 파일을 볼 수 있습니다 .L0 연산은 5를 스택에 넣고 로컬 변수 테이블에 저장합니다
.L1 연산은 먼저 ILOAD 0 (즉, 스택 j의 값에 5를로드), 그런 다음 IINC 0 1 (Add one operation), 마지막으로 ISTORE 1 (i는 6에 할당 됨) 즉, j는 먼저 i 값을 5로 가져온 다음 ++ 연산을 수행하여 i에 할당합니다. 사실 저는 아직 6 살입니다

b 메서드의 바이트 코드 파일 인 L1 연산은 IINC 0 1 (i에 1을 먼저 추가하면 6), ILOAD 0 (i 값이 6이 스택에로드 됨), 마지막으로 ISTORE 1 (할당 j 6) 즉, 고급 ++ 연산을 한 다음 j를 할당합니다.

4. Klass 모델

4.1 Klass 모델
여기에 사진 설명 삽입
4.2 일반 Java 클래스는 JVM의 instanceKlass 클래스에 해당하며 다음과 같은 3 개의 단어 클래스가 있습니다.
4.21 InstanceMirrorKlass : java.lang.Class, Java 코드에서 얻은 클래스 객체를 나타내는 데 사용됩니다. 실제로이 C ++의 인스턴스입니다. 클래스, 힙 영역에 저장되는 과학적 이름 미러 클래스
4.22 InstanceRefKlass : java / lang / ref / Reference 클래스의 하위 클래스 를 나타내는
데 사용됩니다. 4.23 InstanceClassLoaderKlass : 특정 로더에 의해로드 된 클래스를 탐색하는 데 사용됩니다.

4.3 Java의 배열은 정적 데이터 유형이 아니라 런타임 중에 생성되는 동적 데이터 유형입니다. Java 배열의 메타 정보는 ArrayKlass의 하위 클래스로 표시됩니다.
4.31 TypeArrayKlass : 기본 유형을 나타내는
데 사용되는 배열 4.32 ObjArrayKlass : 사용됨 배열 참조 유형

  1. Constant Pool
    5.1 상수 풀 의 맨 아래 계층은 StringTable이고 맨 아래 계층은 HashTable HashTable입니다. Java에서 항목 인 소스 코드 단위를 볼 수 있습니다. 다음으로 코드로 이동하여 어떤 일이 발생했는지 살펴 보겠습니다. 메모리를 선택하고이 메모리를 선택합니다.
    여기에 사진 설명 삽입
public static void main(String[] args) {
    
    
    a();
    b();

}

public static void a() {
    
    
    String str = "11";
    String str1 = "11";
}

public static void b() {
    
    
    String str = new String("11");
    String str1 = new String("22");
}

1. String str = "11"; 우리는 char [] +1, j String +1
이 상수 풀로 이동하여 11이 아닌 경우 상수 11을 찾은 다음 String 객체를 생성하고 char을로드합니다. 문자열 내부에 배열 한 다음 푸시 상수 풀 상수 풀로 이동하면 11 개의 데이터
여기에 사진 설명 삽입
2가
포함 된 항목이 생성됩니다 . 두 번째 문자열 str1 = "11", 이 코드 줄은 먼저 상수 풀로 가서 11을 찾은 다음 str1은 str
여기에 사진 설명 삽입
3이
가리키는 String 객체를 가리 켰습니다. String str = new String ( "11"); String +1 만 있다는 것을 알 수 있습니다. 즉, 11 유형의 데이터가 이미 존재하므로 새 데이터 만 있습니다. 필요
여기에 사진 설명 삽입
4. 문자열 STR1 새로운 문자열 = ( "22").
먼저 발견되지 않는 경우는, 문자열의 목적은 첫 번째 예와 동일한 의미 제 "22"실행 (11)을 찾기 위해 상수 풀로 이동 및 char 배열을 사용한 다음 new String () 생성자를 실행하여 String 객체를 생성합니다.

여기에 사진 설명 삽입
요약 :
String str = "11",
여러 String 객체가 생성되면 하나의 String 객체입니다.
여러 객체가 총 생성되면 두 개의 oops가 있습니다 (InstanceKlass TypeArrayKlass).

추천

출처blog.csdn.net/weixin_45657738/article/details/109474297