2014-04-16 2 views
0

내가 재스민 어셈블리에 새 항목을 만든 다음이를 저장하는 경우는 주소이기 때문에, 내가 지시 aload와 함께 할 : 이제JVM, 정수 풀, 힙과 주소

new Object 
    dup 
    invokespecial..... 
    astore_3 ; load the object reference into local variable 3 

, 동일한 형태와 같은 이러한 주소는 ... 이제

ldc "Great string" 
    astore_3 ; save the reference to the actual string in the constant pool 

을 : 나는 상수 풀에서 문자열을 저장하려면 ... 나는 LDC로를 만들 것입니다 다음뿐만 아니라 aload으로 저장 바이트 수? 이 항목을로드하고 저장하는 데 동일한 명령어를 사용하기 때문에 JVM은 상수 풀에 속한 주소와 힙의 주소를 구별 할 수 있어야합니까?

바이트 코드를 검사 할 때 상수 풀의 실제 주소가 단지 1 바이트 색인 인 것 같습니다 (상수 풀에 대한 기본 참조가 어딘가에 보관되어있는 것 같습니다) ... 이제 그것은 상수 풀에서 som UTF8 데이터에 대한 참조이지만 실제 문자열이있는 곳 또는 다른 곳의 바이트 배열에 대한 참조 일 뿐이라는 것을 알고 있습니까? 내가 할 수 없었던 힙에서 "새로운 객체"의 주소를 검사해라. 기본적으로, 나는이 두 메모리 영역이 같은 형태의 명령어와 JVM이 어떻게 관리 할 수 ​​있는지를 알아 내야한다. 주소가 상수 풀의 오프셋인지 아니면 힙의 객체인지 결정하십시오.

+0

나는 당신이 '탐욕'을 의미한다고 믿는다. 'astore'는 변수에 대한 참조를 쓰고, 'aload'는 변수의 참조를 피연산자 스택에로드합니다. –

+0

네, 그건 사실입니다 ... 무모한 .. 감사합니다! :) –

답변

2

바이트 코드는 반드시 .class 파일로 작성된 동일한 바이트 코드와 JVM에 의해 해석되어야합니다. 많은 JVM에서는 바이트 코드를 수행하여 다른 실행 단계에서을 다시 작성합니다.

그래서 HotSpot JVM도 마찬가지입니다. 클래스가 초기화 될 때 HotSpot은 ldc 바이트 코드를 JVM 관련 fast_aldc 바이트 캐시를 갖는 상수 풀의 문자열 항목을 참조하여 CP 캐시의 객체 (즉, java.lang.String 인스턴스)를 참조하는 바이트 코드로 다시 작성합니다. 이러한 fast_aldc 바이트 코드가 처음 실행될 때 JVM은 상수 풀 항목을 해결하고 Java 힙에 String을 만들고이 문자열에 대한 참조로 CP 캐시를 채 웁니다. 동일한 바이트 코드를 추가로 실행하면 JVM은 즉시 CP 캐시에서 참조를 가져 와서 Java 스택에 밀어 넣습니다.

ldc 바이트 코드 (또는 재 작성된 양식) 해석 후 스택 맨 위에는 Java 힙의 오브젝트에 대한 유효한 참조가 포함됩니다. 동일한 종류의 참조가 바이트 코드 new에 의해 생성됩니다. 따라서 참조 유형을 구별 할 필요가 없습니다.

이렇게 통역사가 작동합니다.물론, 메소드가 JIT 컴파일 된 후에는 더 이상 바이트 코드, 상수 풀 참조 등은 없습니다.이 모든 것은 단지 추상화입니다. 그냥 모델.

+0

우수 답변! 고마워요 ... 당신이 말하는 것이 사실이라고 생각합니다. 약간의 설명입니다. String 클래스를 체크하고 각각의 문자열이 클래스 변수로서 보유하고있는 기본 바이트 버퍼 자체는 배열 객체와 참조가되어야합니다. 힙 ... 그래? –

+0

예. 'Java 힙에 새로운 문자열이 생성되었습니다'라는 말은 heap에 새로운 char [] 배열이 할당되고이 배열을 래핑하는 java.lang.String 객체를 의미합니다. – apangin

0

먼저 바이트 코드 형식 전체는 VM에서 제공하는 추상화에 불과합니다. 런타임시 코드 또는 메모리의 실제 표현과 닮은 것은 반드시 없습니다.

둘째로, 상수 풀은 16 비트 인덱스를 사용하는 최대 65,535 개의 항목으로 구성된 테이블입니다. 작은 인덱스와 카테고리 1 타입으로 상수 풀을 인덱싱하는 것은 일반적인 작업이므로 ldc라는 특별한 속기 명령어가 있습니다.

ldc 명령은 단일 바이트 인덱스를 사용하므로 처음 255 개 항목에서만 사용할 수 있습니다. 그 이상의 항목에 액세스하려면 ldc_w라는 2 바이트 형식을 사용해야합니다. 이 상황은 aload_3 대 aload 3 및 wide aload 3과 같은 다른 속기 명령어와 유사합니다.

다시 말해서이 모든 것은 추상화입니다. 실제로 VM은 상수 풀을 더 친숙한 내부 형식으로 변환하고 런타임 위치에 대한 실제 포인터를 코드로 컴파일 할 수 있습니다. 그러나 그것은 단지 하나의 가능한 구현 일뿐입니다.

관련 문제