2010-12-12 4 views
36

C++에는 다중 상속이 있습니다. 어셈블리 레벨에서 다중 상속을 구현하는 것은 꽤 복잡 할 수 있지만 정상적으로 수행되는 방법 (vtables, 포인터 픽스 업, 썽크 등)은 온라인에서 descriptions 온라인으로 양호합니다.자바 인터페이스는 내부적으로 어떻게 구현됩니까? (vtables?)

Java에는 다중 구현 상속이 없지만 여러 인터페이스 상속이 있으므로 클래스 당 하나의 vtable로 간단하게 구현할 수 있다고 생각하지 않습니다. Java는 내부적으로 인터페이스를 어떻게 구현합니까?

나는 C++과는 달리 Java가 Jit 컴파일되어 있으므로 다른 코드 조각이 다르게 최적화 될 수 있으며 다른 JVM이 다른 방식으로 작업을 수행 할 수 있다는 것을 알고 있습니다. 그렇다면 많은 JVM이이를 따르는 몇 가지 일반적인 전략이 있습니까? 아니면 특정 JVM에서 구현을 아는 사람이 있습니까?

또한 JVM은 종종 가상화 및 인라인 메서드 호출을 포함하지만 vtable 또는 이와 동등한 것이 전혀 없으므로 가상/인터페이스 메서드 호출을 구현하는 실제 어셈블리 시퀀스에 대해 묻는 것이 바람직하지 않을 수 있습니다. JVM은 모든 것을 가상화 할 수없는 경우에도 클래스의 일반적인 표현을 계속 사용합니다. 이 가정이 잘못 되었습니까? 이 표현은 C++ vtable과 같은 방식으로 보입니까? 그렇다면 인터페이스에 별도의 vtable이 있으며 클래스 vtable과이 인터페이스는 어떻게 연결됩니까? 그렇다면 객체 인스턴스가 C++의 객체 인스턴스와 같은 vtable 포인터 (클래스/인터페이스 vtables)를 가질 수 있습니까? 동일한 객체에 대한 클래스 유형 및 인터페이스 유형의 참조는 항상 동일한 이진 값을 갖습니까? 아니면 포인터 수정을 필요로하는 C++에서와 같이 다를 수 있습니까?

는 (참조 : this question는 CLR에 대해 비슷한 것을 요청하고, 그가 나는 자바에 대한 유사한 아무것도 찾을 수가 없었다 이제 구식이 될 수 있지만 this msdn article에 좋은 설명이있을 나타납니다..)

편집 : 나는하지 Java 클래스의 ArrayList "의 의미의"GCC 컴파일러는 정수 추가/함수 호출/등을 구현 않는 방법 "의 의미에서 '구현'을 의미

  • 는 List 인터페이스를 구현 ".
  • 나는 이것이 JVM 바이트 코드 레벨에서 어떻게 작동하는지 알고있다. 클래스 파일을로드하고 바이트 코드를 컴파일 한 후에 어떤 종류의 코드와 데이터 구조가 JVM에 의해 생성되는지 알고 싶다.
+2

인터페이스 상속 및 구현 상속을 언급했습니다. 구현 상속은 정의 된 검색 순서가 필요할 때 어렵습니다. 인터페이스 상속은 훨씬 간단합니다. 구현할 필요가있는 모든 메소드 서명이있는지도 만 있습니다. 검색 순서가 필요하지 않습니다 (검색에 첨부 된 구현이 없음). 거기에 명령이 없습니다. – extraneon

답변

25

핫스팟 JVM의 핵심 기능은 inline caching입니다. 이것은 실제로 대상 메서드가 인라인된다는 것을 의미하지 않지만 나중에 가상 또는 인터페이스 메서드를 호출 할 때마다 이라는 호출이 모두 동일한 구현을 목표로한다는 가정하에 이 JIT 코드에 삽입된다는 것을 의미합니다 (즉 호출 사이트는 단일 형태). 이 경우, 검사는 가정이 실제로 유지되는지 여부 (예 : 대상 개체의 유형이 지난 시간과 동일한 지 여부)에 따라 컴퓨터 코드로 컴파일 된 다음 대상 메서드에 직접 전송합니다. 가상 테이블이 전혀 필요 없습니다. 어설 션이 실패하면, 이것을 megamorphic 콜 사이트 (즉, 가능한 여러 유형들)로 변환하려고 시도 할 수있다; 이것도 실패하면 (또는 첫 번째 호출 인 경우) vtables (가상 메소드 용) 및 itables (인터페이스 용)를 사용하여 규칙적으로 장황한 검색이 수행됩니다.

편집 다음 Hotspot Wiki는 VTABLE과 itable 스텁에 대한 자세한 내용이 있습니다.다형성의 경우에도 여전히 호출 사이트에 인라인 캐시 버전이 저장됩니다. 그러나 코드는 실제로 vtable 또는 itable에서 조회를 수행하는 스텁입니다. 각 vtable 오프셋 (0, 1, 2, ...)에 대해 하나의 vtable 스텁이 있습니다. Interface calls 주어진 오프셋에서 itable (찾은 경우)을 조사하기 전에 itable의 배열에 대한 선형 검색을 추가하십시오.

+0

VirtualCalls 및 InterfaceCalls의 Hotspot Wiki 페이지가 내가 원하는 것 같습니다. 그래도 모든 것을 읽을 수 있어야합니다. – JanKanis

+1

Wiki가 https://wikis.oracle.com/display/HotSpotInternals/Home으로 이동되었습니다. –

+0

oracle wiki가 고정되었으므로 https://wiki.openjdk.java.net/display/HotSpot/Main이 고정되어 있습니다. 여기서 업데이트 할 수있는 정보가 종료되었습니다. – JanKanis

관련 문제